Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)

## [Unreleased]

### Fixed
- `GratefulPatientFeaturizer` now reports one fallback `general` service line
per known donor when the encounter table omits the service-line column.
Missing physician columns continue to report zero distinct physicians, and
both optional-column paths now have regression coverage. Closes #151.

### Changed
- `WealthPercentileTransformer.fit` now raises an actionable `ValueError` when
an explicit `wealth_cols` list matches no training column; partial matches
Expand Down
4 changes: 4 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ contribution. Code, docs, tests, and review all count.
schema mismatches fail with actionable diagnostics and preserved automatic
and partial-match behavior (closes
[#156](https://github.com/PhilanthroPy-Project/PhilanthroPy/issues/156)).
- [@be-student](https://github.com/be-student): aligned the missing service-line
fallback with its `general` category and added regression coverage for
missing service-line and physician columns (closes
[#151](https://github.com/PhilanthroPy-Project/PhilanthroPy/issues/151)).

## Getting listed

Expand Down
2 changes: 1 addition & 1 deletion philanthropy/preprocessing/_grateful_patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def fit(self: _Self, X: Any, y: Any = None) -> _Self:
"general", index=grouped.groups.keys()
)
summary_parts["distinct_service_lines"] = pd.Series(
0, dtype=int, index=grouped.groups.keys()
1, dtype=int, index=grouped.groups.keys()
)

if self.physician_col in raw_enc.columns:
Expand Down
26 changes: 26 additions & 0 deletions tests/test_grateful_patient_featurizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,32 @@ def test_missing_drg_weight_col_fills_nan_then_zero_after_transform(
"Without drg_weight_col, total_drg_weight must be 0.0 after fillna"
)

def test_missing_service_line_col_falls_back_to_general(
self, enc_df, X_donors
):
enc = enc_df.drop(columns=["service_line"])
gpf = GratefulPatientFeaturizer(encounter_df=enc).fit(X_donors)

result = gpf.transform(X_donors)
feature_names = list(gpf.get_feature_names_out())
distinct_idx = feature_names.index("distinct_service_lines")

assert result.shape == (len(X_donors), len(feature_names))
assert np.isfinite(result).all()
np.testing.assert_array_equal(result[:4, distinct_idx], 1.0)

def test_missing_physician_col_yields_zero_distinct_physicians(
self, enc_df, X_donors
):
enc = enc_df.drop(columns=["attending_physician_id"])
gpf = GratefulPatientFeaturizer(encounter_df=enc).fit(X_donors)

result = gpf.transform(X_donors)
feature_names = list(gpf.get_feature_names_out())
physician_idx = feature_names.index("distinct_physicians")

np.testing.assert_array_equal(result[:4, physician_idx], 0.0)

def test_drg_weight_col_sums_correctly(self, X_donors):
"""With drg_weight_col present, total_drg_weight must sum DRG weights per donor."""
enc = pd.DataFrame({
Expand Down