Skip to content

Commit 03de01e

Browse files
vahid-ahmadiclaude
andcommitted
Always store MicroDataFrame weights as a Series
nullify_weights and the deprecated set_weight_col assigned a bare np.ndarray to self.weights, while the rest of the class assumes an index-aligned Series. After either call, equals() raised AttributeError: 'numpy.ndarray' object has no attribute 'equals', and the .weights.reindex() calls in __getitem__ and the loc indexer were one step from the same failure. set_weight_col also skipped the length validation and index alignment that set_weights performs. Both now delegate to set_weights. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 46cffbd commit 03de01e

3 files changed

Lines changed: 35 additions & 5 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- bump: patch
2+
changes:
3+
fixed:
4+
- MicroDataFrame.nullify_weights and set_weight_col now store weights as an
5+
index-aligned Series instead of a bare ndarray, so equals() no longer
6+
raises.

microdf/microdataframe.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -362,18 +362,20 @@ def set_weight_col(self, column: str, preserve_old: Optional[bool] = False) -> N
362362
if preserve_old and self.weights_col is not None:
363363
self["old_" + self.weights_col] = self.weights
364364

365-
self.weights = np.array(self[column])
366-
self.weights_col = column
367-
self._link_all_weights()
365+
# Delegate to set_weights: it validates length and builds an
366+
# index-aligned float Series rather than a bare ndarray.
367+
self.set_weights(column)
368368

369369
def nullify_weights(self) -> None:
370370
"""Set all weights to 1, effectively making the DataFrame unweighted.
371371
372372
This is useful for comparing weighted and unweighted statistics or when
373373
you want to temporarily ignore weights.
374374
"""
375-
self.weights = np.ones(len(self))
376-
self._link_all_weights()
375+
# Route through set_weights so self.weights stays an index-aligned
376+
# float Series. Assigning a bare ndarray here broke every caller
377+
# that treats it as a Series (equals(), reindex() in __getitem__).
378+
self.set_weights(np.ones(len(self)))
377379

378380
def __getitem__(
379381
self, key: Union[str, List]

microdf/tests/test_microseries_dataframe.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,3 +815,25 @@ def test_rank_ties_share_bucket() -> None:
815815
# existing ``test_rank`` expectations hold.
816816
s = mdf.MicroSeries([1, 2, 3], weights=[4, 5, 6])
817817
np.testing.assert_array_equal(s.rank().values, [4, 9, 15])
818+
819+
820+
def test_weights_stay_a_series_after_nullify():
821+
"""nullify_weights must leave weights as an index-aligned Series."""
822+
df = mdf.MicroDataFrame(pd.DataFrame({"x": [1, 2, 3]}), weights=[4, 5, 6])
823+
df.nullify_weights()
824+
assert isinstance(df.weights, pd.Series)
825+
assert list(df.weights.index) == list(df.index)
826+
assert df.equals(df)
827+
assert df.sum()["x"] == 6
828+
829+
830+
def test_weights_stay_a_series_after_set_weight_col():
831+
"""The deprecated set_weight_col must also produce a Series."""
832+
df = mdf.MicroDataFrame(pd.DataFrame({"x": [1, 2, 3], "w": [1.0, 2.0, 3.0]}))
833+
with warnings.catch_warnings():
834+
warnings.simplefilter("ignore", DeprecationWarning)
835+
df.set_weight_col("w")
836+
assert isinstance(df.weights, pd.Series)
837+
assert df.weights_col == "w"
838+
assert df.equals(df)
839+
assert df.sum()["x"] == 14

0 commit comments

Comments
 (0)