From a5e392a2bd7082dc153c48e5771de9cfefd91341 Mon Sep 17 00:00:00 2001 From: baogorek Date: Wed, 23 Jul 2025 16:29:26 -0400 Subject: [PATCH 1/4] add test that should fail --- microdf/tests/test_microseries_dataframe.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/microdf/tests/test_microseries_dataframe.py b/microdf/tests/test_microseries_dataframe.py index 6a22d83..de75ab4 100644 --- a/microdf/tests/test_microseries_dataframe.py +++ b/microdf/tests/test_microseries_dataframe.py @@ -24,6 +24,15 @@ def test_df_init() -> None: assert df.a.mean() == np.average(arr, weights=w) +def test_handles_empty_index() -> None: + arr = np.array([0, 1, 1]) + w = np.array([3, 0, 9]) + df = mdf.MicroDataFrame({"a": arr}, weights=w) + + empty_index = pd.Index([]) + df[empty_index] # Implicit assert; checking for ValueError + + def test_series_getitem() -> None: arr = np.array([0, 1, 1]) w = np.array([3, 0, 9]) From c06b687a4233ef3397f50e4664b6ff369cdedd0f Mon Sep 17 00:00:00 2001 From: baogorek Date: Wed, 23 Jul 2025 17:29:36 -0400 Subject: [PATCH 2/4] changelog and newline in an unrelated ipynb to pass lint --- changelog_entry.yaml | 4 ++++ docs/gini.ipynb | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29..f7834a4 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,4 @@ +- bump: patch + changes: + fixed: + - Allowed a MicroDataFrame to handle an empty index subset diff --git a/docs/gini.ipynb b/docs/gini.ipynb index 7b5bffd..9861c36 100644 --- a/docs/gini.ipynb +++ b/docs/gini.ipynb @@ -27,7 +27,7 @@ "# Create sample data\n", "x = [10, 20, 30, 40, 100]\n", "w = [1, 2, 3, 4, 5]\n", - "df = pd.DataFrame({'x': x, 'w': w})" + "df = pd.DataFrame({\"x\": x, \"w\": w})" ] }, { @@ -80,7 +80,7 @@ "outputs": [], "source": [ "# Create a MicroDataFrame\n", - "mdf_df = mdf.MicroDataFrame(df, weights='w')\n", + "mdf_df = mdf.MicroDataFrame(df, weights=\"w\")\n", "\n", "# Access column as MicroSeries and calculate gini\n", "print(f\"Gini from MicroDataFrame column: {mdf_df.x.gini():.4f}\")" From c3da71471b47da13d980c894745e13f341537439 Mon Sep 17 00:00:00 2001 From: baogorek Date: Wed, 23 Jul 2025 21:36:45 -0400 Subject: [PATCH 3/4] make __getitem__ more robust --- microdf/microdataframe.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/microdf/microdataframe.py b/microdf/microdataframe.py index e749c8a..16551f9 100644 --- a/microdf/microdataframe.py +++ b/microdf/microdataframe.py @@ -216,16 +216,18 @@ def set_weight_col( self._link_all_weights() def __getitem__( - self, key: Union[str, List] - ) -> Union[pd.Series, pd.DataFrame]: - result = super().__getitem__(key) - if isinstance(result, pd.DataFrame): - try: - weights = self.weights[key] - except Exception: - weights = self.weights - return MicroDataFrame(result, weights=weights) - return result + self, key: Union[str, List] + ) -> Union[pd.Series, pd.DataFrame]: + # Let pandas handle the initial slicing + result = super().__getitem__(key) + + # If the result is a DataFrame, re-synchronize the weights + if isinstance(result, pd.DataFrame): + new_weights = self.weights.reindex(result.index) + return MicroDataFrame(result, weights=new_weights) + + # Otherwise, the result is a Series or a scalar, so just return it + return result def catch_series_relapse(self) -> None: for col in self.columns: From a4441868a2a19cf6985457819accf1916e59f64a Mon Sep 17 00:00:00 2001 From: baogorek Date: Wed, 23 Jul 2025 21:50:32 -0400 Subject: [PATCH 4/4] linting --- microdf/microdataframe.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/microdf/microdataframe.py b/microdf/microdataframe.py index 16551f9..f43ee27 100644 --- a/microdf/microdataframe.py +++ b/microdf/microdataframe.py @@ -216,18 +216,18 @@ def set_weight_col( self._link_all_weights() def __getitem__( - self, key: Union[str, List] - ) -> Union[pd.Series, pd.DataFrame]: - # Let pandas handle the initial slicing - result = super().__getitem__(key) - - # If the result is a DataFrame, re-synchronize the weights - if isinstance(result, pd.DataFrame): - new_weights = self.weights.reindex(result.index) - return MicroDataFrame(result, weights=new_weights) - - # Otherwise, the result is a Series or a scalar, so just return it - return result + self, key: Union[str, List] + ) -> Union[pd.Series, pd.DataFrame]: + # Let pandas handle the initial slicing + result = super().__getitem__(key) + + # If the result is a DataFrame, re-synchronize the weights + if isinstance(result, pd.DataFrame): + new_weights = self.weights.reindex(result.index) + return MicroDataFrame(result, weights=new_weights) + + # Otherwise, the result is a Series or a scalar, so just return it + return result def catch_series_relapse(self) -> None: for col in self.columns: