diff --git a/changelog.d/weights-always-series.yaml b/changelog.d/weights-always-series.yaml new file mode 100644 index 0000000..814199a --- /dev/null +++ b/changelog.d/weights-always-series.yaml @@ -0,0 +1,6 @@ +- bump: patch + changes: + fixed: + - MicroDataFrame.nullify_weights and set_weight_col now store weights as an + index-aligned Series instead of a bare ndarray, so equals() no longer + raises. diff --git a/microdf/microdataframe.py b/microdf/microdataframe.py index 7d9e7c4..34c2253 100644 --- a/microdf/microdataframe.py +++ b/microdf/microdataframe.py @@ -362,9 +362,9 @@ def set_weight_col(self, column: str, preserve_old: Optional[bool] = False) -> N if preserve_old and self.weights_col is not None: self["old_" + self.weights_col] = self.weights - self.weights = np.array(self[column]) - self.weights_col = column - self._link_all_weights() + # Delegate to set_weights: it validates length and builds an + # index-aligned float Series rather than a bare ndarray. + self.set_weights(column) def nullify_weights(self) -> None: """Set all weights to 1, effectively making the DataFrame unweighted. @@ -372,8 +372,10 @@ def nullify_weights(self) -> None: This is useful for comparing weighted and unweighted statistics or when you want to temporarily ignore weights. """ - self.weights = np.ones(len(self)) - self._link_all_weights() + # Route through set_weights so self.weights stays an index-aligned + # float Series. Assigning a bare ndarray here broke every caller + # that treats it as a Series (equals(), reindex() in __getitem__). + self.set_weights(np.ones(len(self))) def __getitem__( self, key: Union[str, List] diff --git a/microdf/tests/test_microseries_dataframe.py b/microdf/tests/test_microseries_dataframe.py index a73e8bb..4bc2d4a 100644 --- a/microdf/tests/test_microseries_dataframe.py +++ b/microdf/tests/test_microseries_dataframe.py @@ -815,3 +815,25 @@ def test_rank_ties_share_bucket() -> None: # existing ``test_rank`` expectations hold. s = mdf.MicroSeries([1, 2, 3], weights=[4, 5, 6]) np.testing.assert_array_equal(s.rank().values, [4, 9, 15]) + + +def test_weights_stay_a_series_after_nullify(): + """nullify_weights must leave weights as an index-aligned Series.""" + df = mdf.MicroDataFrame(pd.DataFrame({"x": [1, 2, 3]}), weights=[4, 5, 6]) + df.nullify_weights() + assert isinstance(df.weights, pd.Series) + assert list(df.weights.index) == list(df.index) + assert df.equals(df) + assert df.sum()["x"] == 6 + + +def test_weights_stay_a_series_after_set_weight_col(): + """The deprecated set_weight_col must also produce a Series.""" + df = mdf.MicroDataFrame(pd.DataFrame({"x": [1, 2, 3], "w": [1.0, 2.0, 3.0]})) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + df.set_weight_col("w") + assert isinstance(df.weights, pd.Series) + assert df.weights_col == "w" + assert df.equals(df) + assert df.sum()["x"] == 14