microdf-python 1.2.2__py3-none-any.whl → 1.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- microdf/microdataframe.py +14 -34
- microdf/microseries.py +14 -38
- microdf/tests/test_microseries_dataframe.py +7 -21
- microdf/tests/test_pandas3_compatibility.py +27 -33
- {microdf_python-1.2.2.dist-info → microdf_python-1.2.3.dist-info}/METADATA +2 -6
- microdf_python-1.2.3.dist-info/RECORD +11 -0
- microdf_python-1.2.2.dist-info/RECORD +0 -11
- {microdf_python-1.2.2.dist-info → microdf_python-1.2.3.dist-info}/WHEEL +0 -0
- {microdf_python-1.2.2.dist-info → microdf_python-1.2.3.dist-info}/licenses/LICENSE +0 -0
- {microdf_python-1.2.2.dist-info → microdf_python-1.2.3.dist-info}/top_level.txt +0 -0
microdf/microdataframe.py
CHANGED
|
@@ -147,9 +147,7 @@ class MicroDataFrame(pd.DataFrame):
|
|
|
147
147
|
for col in self.columns:
|
|
148
148
|
if pd.api.types.is_numeric_dtype(self[col]):
|
|
149
149
|
try:
|
|
150
|
-
results[col] = getattr(self[col], name)(
|
|
151
|
-
*args, **kwargs
|
|
152
|
-
)
|
|
150
|
+
results[col] = getattr(self[col], name)(*args, **kwargs)
|
|
153
151
|
except Exception:
|
|
154
152
|
# Skip columns that can't be aggregated
|
|
155
153
|
pass
|
|
@@ -224,9 +222,7 @@ class MicroDataFrame(pd.DataFrame):
|
|
|
224
222
|
for col in self.columns:
|
|
225
223
|
if pd.api.types.is_numeric_dtype(self[col]):
|
|
226
224
|
try:
|
|
227
|
-
results[col] = getattr(self[col], name)(
|
|
228
|
-
*args, **kwargs
|
|
229
|
-
)
|
|
225
|
+
results[col] = getattr(self[col], name)(*args, **kwargs)
|
|
230
226
|
except Exception:
|
|
231
227
|
# Skip columns that can't be aggregated
|
|
232
228
|
pass
|
|
@@ -323,9 +319,7 @@ class MicroDataFrame(pd.DataFrame):
|
|
|
323
319
|
self.weights = pd.Series(weights, dtype=float)
|
|
324
320
|
self._link_all_weights()
|
|
325
321
|
|
|
326
|
-
def set_weight_col(
|
|
327
|
-
self, column: str, preserve_old: Optional[bool] = False
|
|
328
|
-
) -> None:
|
|
322
|
+
def set_weight_col(self, column: str, preserve_old: Optional[bool] = False) -> None:
|
|
329
323
|
"""Sets the weights for the MicroDataFrame by specifying the name of
|
|
330
324
|
the weight column.
|
|
331
325
|
|
|
@@ -594,9 +588,7 @@ class MicroDataFrame(pd.DataFrame):
|
|
|
594
588
|
return equal_values and equal_weights
|
|
595
589
|
|
|
596
590
|
@get_args_as_micro_series()
|
|
597
|
-
def groupby(
|
|
598
|
-
self, by: Union[str, List], *args, **kwargs
|
|
599
|
-
) -> "MicroDataFrameGroupBy":
|
|
591
|
+
def groupby(self, by: Union[str, List], *args, **kwargs) -> "MicroDataFrameGroupBy":
|
|
600
592
|
"""Returns a GroupBy object with MicroSeriesGroupBy objects for each
|
|
601
593
|
column.
|
|
602
594
|
|
|
@@ -757,14 +749,10 @@ class MicroDataFrameGroupBy(pd.core.groupby.generic.DataFrameGroupBy):
|
|
|
757
749
|
self.columns.remove("__tmp_weights")
|
|
758
750
|
# Filter to only numeric columns
|
|
759
751
|
self.numeric_columns = [
|
|
760
|
-
col
|
|
761
|
-
for col in self.columns
|
|
762
|
-
if pd.api.types.is_numeric_dtype(self.obj[col])
|
|
752
|
+
col for col in self.columns if pd.api.types.is_numeric_dtype(self.obj[col])
|
|
763
753
|
]
|
|
764
754
|
# Store reference to weights groupby for column selection
|
|
765
|
-
self._weights_groupby = copy.deepcopy(
|
|
766
|
-
super().__getitem__("__tmp_weights")
|
|
767
|
-
)
|
|
755
|
+
self._weights_groupby = copy.deepcopy(super().__getitem__("__tmp_weights"))
|
|
768
756
|
for fn_name in MicroSeries.SCALAR_FUNCTIONS:
|
|
769
757
|
|
|
770
758
|
def get_fn(name):
|
|
@@ -854,18 +842,14 @@ class MicroDataFrameGroupBy(pd.core.groupby.generic.DataFrameGroupBy):
|
|
|
854
842
|
results = {}
|
|
855
843
|
for col in res.numeric_columns:
|
|
856
844
|
try:
|
|
857
|
-
results[col] = getattr(
|
|
858
|
-
|
|
859
|
-
)
|
|
845
|
+
results[col] = getattr(getattr(res, col), name)(
|
|
846
|
+
*args, **kwargs
|
|
847
|
+
)
|
|
860
848
|
except Exception:
|
|
861
849
|
pass
|
|
862
850
|
# Return plain DataFrame - aggregated results don't
|
|
863
851
|
# have per-row weights (weights were already applied)
|
|
864
|
-
return (
|
|
865
|
-
pd.DataFrame(results)
|
|
866
|
-
if results
|
|
867
|
-
else pd.DataFrame()
|
|
868
|
-
)
|
|
852
|
+
return pd.DataFrame(results) if results else pd.DataFrame()
|
|
869
853
|
|
|
870
854
|
return fn
|
|
871
855
|
|
|
@@ -877,18 +861,14 @@ class MicroDataFrameGroupBy(pd.core.groupby.generic.DataFrameGroupBy):
|
|
|
877
861
|
results = {}
|
|
878
862
|
for col in res.numeric_columns:
|
|
879
863
|
try:
|
|
880
|
-
results[col] = getattr(
|
|
881
|
-
|
|
882
|
-
)
|
|
864
|
+
results[col] = getattr(getattr(res, col), name)(
|
|
865
|
+
*args, **kwargs
|
|
866
|
+
)
|
|
883
867
|
except Exception:
|
|
884
868
|
pass
|
|
885
869
|
# Return plain DataFrame - aggregated results don't
|
|
886
870
|
# have per-row weights (weights were already applied)
|
|
887
|
-
return (
|
|
888
|
-
pd.DataFrame(results)
|
|
889
|
-
if results
|
|
890
|
-
else pd.DataFrame()
|
|
891
|
-
)
|
|
871
|
+
return pd.DataFrame(results) if results else pd.DataFrame()
|
|
892
872
|
|
|
893
873
|
return fn
|
|
894
874
|
|
microdf/microseries.py
CHANGED
|
@@ -96,9 +96,7 @@ class MicroSeries(pd.Series):
|
|
|
96
96
|
"""
|
|
97
97
|
if weights is None:
|
|
98
98
|
if len(self) > 0:
|
|
99
|
-
self.weights = pd.Series(
|
|
100
|
-
np.ones_like(self._values), dtype=float
|
|
101
|
-
)
|
|
99
|
+
self.weights = pd.Series(np.ones_like(self._values), dtype=float)
|
|
102
100
|
else:
|
|
103
101
|
if len(weights) != len(self):
|
|
104
102
|
raise ValueError(
|
|
@@ -189,9 +187,9 @@ class MicroSeries(pd.Series):
|
|
|
189
187
|
values = np.array(self._values)
|
|
190
188
|
quantiles = np.atleast_1d(q)
|
|
191
189
|
sample_weight = np.array(self.weights)
|
|
192
|
-
assert np.all(quantiles >= 0) and np.all(
|
|
193
|
-
quantiles
|
|
194
|
-
)
|
|
190
|
+
assert np.all(quantiles >= 0) and np.all(quantiles <= 1), (
|
|
191
|
+
"quantiles should be in [0, 1]"
|
|
192
|
+
)
|
|
195
193
|
sorter = np.argsort(values)
|
|
196
194
|
values = values[sorter]
|
|
197
195
|
sample_weight = sample_weight[sorter]
|
|
@@ -199,11 +197,7 @@ class MicroSeries(pd.Series):
|
|
|
199
197
|
cumsum_normalized = cumsum / cumsum[-1]
|
|
200
198
|
result = np.array(
|
|
201
199
|
[
|
|
202
|
-
values[
|
|
203
|
-
min(
|
|
204
|
-
np.searchsorted(cumsum_normalized, qi), len(values) - 1
|
|
205
|
-
)
|
|
206
|
-
]
|
|
200
|
+
values[min(np.searchsorted(cumsum_normalized, qi), len(values) - 1)]
|
|
207
201
|
for qi in quantiles
|
|
208
202
|
]
|
|
209
203
|
)
|
|
@@ -454,9 +448,7 @@ class MicroSeries(pd.Series):
|
|
|
454
448
|
return MicroSeries(res, weights=self.weights)
|
|
455
449
|
return self
|
|
456
450
|
|
|
457
|
-
def round(
|
|
458
|
-
self, decimals: Optional[int] = 0, *args, **kwargs
|
|
459
|
-
) -> "MicroSeries":
|
|
451
|
+
def round(self, decimals: Optional[int] = 0, *args, **kwargs) -> "MicroSeries":
|
|
460
452
|
res = super().round(decimals=decimals, *args, **kwargs)
|
|
461
453
|
return MicroSeries(res, weights=self.weights)
|
|
462
454
|
|
|
@@ -488,14 +480,10 @@ class MicroSeries(pd.Series):
|
|
|
488
480
|
def __mul__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
489
481
|
return MicroSeries(super().__mul__(other), weights=self.weights)
|
|
490
482
|
|
|
491
|
-
def __floordiv__(
|
|
492
|
-
self, other: Union[int, float, pd.Series]
|
|
493
|
-
) -> "MicroSeries":
|
|
483
|
+
def __floordiv__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
494
484
|
return MicroSeries(super().__floordiv__(other), weights=self.weights)
|
|
495
485
|
|
|
496
|
-
def __truediv__(
|
|
497
|
-
self, other: Union[int, float, pd.Series]
|
|
498
|
-
) -> "MicroSeries":
|
|
486
|
+
def __truediv__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
499
487
|
return MicroSeries(super().__truediv__(other), weights=self.weights)
|
|
500
488
|
|
|
501
489
|
def __mod__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
@@ -525,14 +513,10 @@ class MicroSeries(pd.Series):
|
|
|
525
513
|
def __rmul__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
526
514
|
return MicroSeries(super().__rmul__(other), weights=self.weights)
|
|
527
515
|
|
|
528
|
-
def __rfloordiv__(
|
|
529
|
-
self, other: Union[int, float, pd.Series]
|
|
530
|
-
) -> "MicroSeries":
|
|
516
|
+
def __rfloordiv__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
531
517
|
return MicroSeries(super().__rfloordiv__(other), weights=self.weights)
|
|
532
518
|
|
|
533
|
-
def __rtruediv__(
|
|
534
|
-
self, other: Union[int, float, pd.Series]
|
|
535
|
-
) -> "MicroSeries":
|
|
519
|
+
def __rtruediv__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
536
520
|
return MicroSeries(super().__rtruediv__(other), weights=self.weights)
|
|
537
521
|
|
|
538
522
|
def __rmod__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
@@ -585,17 +569,13 @@ class MicroSeries(pd.Series):
|
|
|
585
569
|
def __imul__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
586
570
|
return MicroSeries(super().__imul__(other), weights=self.weights)
|
|
587
571
|
|
|
588
|
-
def __ifloordiv__(
|
|
589
|
-
self, other: Union[int, float, pd.Series]
|
|
590
|
-
) -> "MicroSeries":
|
|
572
|
+
def __ifloordiv__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
591
573
|
return MicroSeries(super().__ifloordiv__(other), weights=self.weights)
|
|
592
574
|
|
|
593
575
|
def __idiv__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
594
576
|
return MicroSeries(super().__idiv__(other), weights=self.weights)
|
|
595
577
|
|
|
596
|
-
def __itruediv__(
|
|
597
|
-
self, other: Union[int, float, pd.Series]
|
|
598
|
-
) -> "MicroSeries":
|
|
578
|
+
def __itruediv__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
599
579
|
return MicroSeries(super().__itruediv__(other), weights=self.weights)
|
|
600
580
|
|
|
601
581
|
def __imod__(self, other: Union[int, float, pd.Series]) -> "MicroSeries":
|
|
@@ -666,16 +646,12 @@ class MicroSeriesGroupBy(pd.core.groupby.generic.SeriesGroupBy):
|
|
|
666
646
|
def _init(self):
|
|
667
647
|
def _weighted_agg(name) -> Callable:
|
|
668
648
|
def via_micro_series(row, *args, **kwargs):
|
|
669
|
-
return getattr(MicroSeries(row.a, weights=row.w), name)(
|
|
670
|
-
*args, **kwargs
|
|
671
|
-
)
|
|
649
|
+
return getattr(MicroSeries(row.a, weights=row.w), name)(*args, **kwargs)
|
|
672
650
|
|
|
673
651
|
fn = getattr(MicroSeries, name)
|
|
674
652
|
|
|
675
653
|
@wraps(fn)
|
|
676
|
-
def _weighted_agg_fn(
|
|
677
|
-
*args, **kwargs
|
|
678
|
-
) -> Union[pd.Series, pd.DataFrame]:
|
|
654
|
+
def _weighted_agg_fn(*args, **kwargs) -> Union[pd.Series, pd.DataFrame]:
|
|
679
655
|
arrays = self.apply(np.array)
|
|
680
656
|
weights = self.weights.apply(np.array)
|
|
681
657
|
df = pd.DataFrame(dict(a=arrays, w=weights))
|
|
@@ -261,9 +261,7 @@ def test_decile_rank() -> None:
|
|
|
261
261
|
|
|
262
262
|
|
|
263
263
|
def test_copy_equals() -> None:
|
|
264
|
-
d = mdf.MicroDataFrame(
|
|
265
|
-
{"x": [1, 2], "y": [3, 4], "z": [5, 6]}, weights=[7, 8]
|
|
266
|
-
)
|
|
264
|
+
d = mdf.MicroDataFrame({"x": [1, 2], "y": [3, 4], "z": [5, 6]}, weights=[7, 8])
|
|
267
265
|
d_copy = d.copy()
|
|
268
266
|
d_copy_diff_weights = d_copy.copy()
|
|
269
267
|
d_copy_diff_weights.weights *= 2
|
|
@@ -275,9 +273,7 @@ def test_copy_equals() -> None:
|
|
|
275
273
|
|
|
276
274
|
|
|
277
275
|
def test_subset() -> None:
|
|
278
|
-
df = mdf.MicroDataFrame(
|
|
279
|
-
{"x": [1, 2], "y": [3, 4], "z": [5, 6]}, weights=[7, 8]
|
|
280
|
-
)
|
|
276
|
+
df = mdf.MicroDataFrame({"x": [1, 2], "y": [3, 4], "z": [5, 6]}, weights=[7, 8])
|
|
281
277
|
df_no_z = mdf.MicroDataFrame({"x": [1, 2], "y": [3, 4]}, weights=[7, 8])
|
|
282
278
|
assert df[["x", "y"]].equals(df_no_z)
|
|
283
279
|
df_no_z_diff_weights = df_no_z.copy()
|
|
@@ -353,9 +349,7 @@ def test_reset_index_inplace() -> None:
|
|
|
353
349
|
# Test 4: Multi-level index
|
|
354
350
|
arrays = [["bar", "bar", "baz", "baz"], ["one", "two", "one", "two"]]
|
|
355
351
|
multi_index = pd.MultiIndex.from_arrays(arrays, names=["first", "second"])
|
|
356
|
-
df_multi = pd.DataFrame(
|
|
357
|
-
{"A": [1, 2, 3, 4], "B": [5, 6, 7, 8]}, index=multi_index
|
|
358
|
-
)
|
|
352
|
+
df_multi = pd.DataFrame({"A": [1, 2, 3, 4], "B": [5, 6, 7, 8]}, index=multi_index)
|
|
359
353
|
mdf_multi = MicroDataFrame(df_multi, weights=weights)
|
|
360
354
|
result = mdf_multi.reset_index(level="first")
|
|
361
355
|
assert "first" in result.columns
|
|
@@ -373,9 +367,7 @@ def test_reset_index_inplace() -> None:
|
|
|
373
367
|
def test_loc_preserves_weights() -> None:
|
|
374
368
|
"""Test that .loc[] returns MicroDataFrame with proper weights (issue
|
|
375
369
|
#265)."""
|
|
376
|
-
df = mdf.MicroDataFrame(
|
|
377
|
-
{"one": [1, 1, 1, 1, 1]}, weights=[10, 20, 30, 40, 50]
|
|
378
|
-
)
|
|
370
|
+
df = mdf.MicroDataFrame({"one": [1, 1, 1, 1, 1]}, weights=[10, 20, 30, 40, 50])
|
|
379
371
|
|
|
380
372
|
# Filter all rows (should get same weights)
|
|
381
373
|
filtered = df.loc[df.one == 1]
|
|
@@ -383,9 +375,7 @@ def test_loc_preserves_weights() -> None:
|
|
|
383
375
|
assert filtered.one.sum() == 150.0 # Weighted sum
|
|
384
376
|
|
|
385
377
|
# Partial filter
|
|
386
|
-
df2 = mdf.MicroDataFrame(
|
|
387
|
-
{"x": [1, 2, 3, 4, 5]}, weights=[10, 20, 30, 40, 50]
|
|
388
|
-
)
|
|
378
|
+
df2 = mdf.MicroDataFrame({"x": [1, 2, 3, 4, 5]}, weights=[10, 20, 30, 40, 50])
|
|
389
379
|
subset = df2.loc[df2.x > 2]
|
|
390
380
|
assert isinstance(subset, MicroDataFrame)
|
|
391
381
|
assert subset.x.sum() == 500.0 # 3*30 + 4*40 + 5*50 = 500
|
|
@@ -394,9 +384,7 @@ def test_loc_preserves_weights() -> None:
|
|
|
394
384
|
|
|
395
385
|
def test_iloc_preserves_weights() -> None:
|
|
396
386
|
"""Test that .iloc[] returns MicroDataFrame with proper weights."""
|
|
397
|
-
df = mdf.MicroDataFrame(
|
|
398
|
-
{"x": [1, 2, 3, 4, 5]}, weights=[10, 20, 30, 40, 50]
|
|
399
|
-
)
|
|
387
|
+
df = mdf.MicroDataFrame({"x": [1, 2, 3, 4, 5]}, weights=[10, 20, 30, 40, 50])
|
|
400
388
|
|
|
401
389
|
# Select rows by position
|
|
402
390
|
subset = df.iloc[2:5]
|
|
@@ -407,9 +395,7 @@ def test_iloc_preserves_weights() -> None:
|
|
|
407
395
|
|
|
408
396
|
def test_groupby_column_selection() -> None:
|
|
409
397
|
"""Test that groupby column selection preserves weights (issue #193)."""
|
|
410
|
-
d = mdf.MicroDataFrame(
|
|
411
|
-
dict(g=["a", "a", "b"], y=[1, 2, 3]), weights=[4, 5, 6]
|
|
412
|
-
)
|
|
398
|
+
d = mdf.MicroDataFrame(dict(g=["a", "a", "b"], y=[1, 2, 3]), weights=[4, 5, 6])
|
|
413
399
|
|
|
414
400
|
# Test single column string selection
|
|
415
401
|
result_str = d.groupby("g")["y"].sum()
|
|
@@ -38,23 +38,23 @@ class TestMicroSeriesSubclassPreservation:
|
|
|
38
38
|
|
|
39
39
|
# Addition
|
|
40
40
|
result = ms + 1
|
|
41
|
-
assert isinstance(
|
|
42
|
-
result
|
|
43
|
-
)
|
|
41
|
+
assert isinstance(result, MicroSeries), (
|
|
42
|
+
f"Got {type(result)} instead of MicroSeries"
|
|
43
|
+
)
|
|
44
44
|
assert hasattr(result, "weights")
|
|
45
45
|
assert hasattr(result, "set_weights")
|
|
46
46
|
|
|
47
47
|
# Multiplication
|
|
48
48
|
result = ms * 2
|
|
49
|
-
assert isinstance(
|
|
50
|
-
result
|
|
51
|
-
)
|
|
49
|
+
assert isinstance(result, MicroSeries), (
|
|
50
|
+
f"Got {type(result)} instead of MicroSeries"
|
|
51
|
+
)
|
|
52
52
|
|
|
53
53
|
# Division
|
|
54
54
|
result = ms / 2
|
|
55
|
-
assert isinstance(
|
|
56
|
-
result
|
|
57
|
-
)
|
|
55
|
+
assert isinstance(result, MicroSeries), (
|
|
56
|
+
f"Got {type(result)} instead of MicroSeries"
|
|
57
|
+
)
|
|
58
58
|
|
|
59
59
|
def test_microseries_preserved_after_comparison(self):
|
|
60
60
|
"""Comparison operations should return MicroSeries, not plain
|
|
@@ -63,35 +63,33 @@ class TestMicroSeriesSubclassPreservation:
|
|
|
63
63
|
|
|
64
64
|
# Greater than
|
|
65
65
|
result = ms > 1
|
|
66
|
-
assert isinstance(
|
|
67
|
-
result
|
|
68
|
-
)
|
|
66
|
+
assert isinstance(result, MicroSeries), (
|
|
67
|
+
f"Got {type(result)} instead of MicroSeries"
|
|
68
|
+
)
|
|
69
69
|
assert hasattr(result, "weights")
|
|
70
70
|
|
|
71
71
|
# Less than
|
|
72
72
|
result = ms < 3
|
|
73
|
-
assert isinstance(
|
|
74
|
-
result
|
|
75
|
-
)
|
|
73
|
+
assert isinstance(result, MicroSeries), (
|
|
74
|
+
f"Got {type(result)} instead of MicroSeries"
|
|
75
|
+
)
|
|
76
76
|
|
|
77
77
|
def test_microseries_preserved_after_indexing(self):
|
|
78
78
|
"""Indexing operations should return MicroSeries, not plain Series."""
|
|
79
|
-
ms = MicroSeries(
|
|
80
|
-
[1, 2, 3, 4, 5], weights=np.array([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
81
|
-
)
|
|
79
|
+
ms = MicroSeries([1, 2, 3, 4, 5], weights=np.array([1.0, 2.0, 3.0, 4.0, 5.0]))
|
|
82
80
|
|
|
83
81
|
# Boolean indexing
|
|
84
82
|
result = ms[ms > 2]
|
|
85
|
-
assert isinstance(
|
|
86
|
-
result
|
|
87
|
-
)
|
|
83
|
+
assert isinstance(result, MicroSeries), (
|
|
84
|
+
f"Got {type(result)} instead of MicroSeries"
|
|
85
|
+
)
|
|
88
86
|
assert hasattr(result, "weights")
|
|
89
87
|
|
|
90
88
|
# Slice indexing
|
|
91
89
|
result = ms[1:3]
|
|
92
|
-
assert isinstance(
|
|
93
|
-
result
|
|
94
|
-
)
|
|
90
|
+
assert isinstance(result, MicroSeries), (
|
|
91
|
+
f"Got {type(result)} instead of MicroSeries"
|
|
92
|
+
)
|
|
95
93
|
|
|
96
94
|
|
|
97
95
|
class TestMicroDataFrameSubclassPreservation:
|
|
@@ -105,9 +103,7 @@ class TestMicroDataFrameSubclassPreservation:
|
|
|
105
103
|
|
|
106
104
|
# Column access
|
|
107
105
|
col = mdf["a"]
|
|
108
|
-
assert isinstance(
|
|
109
|
-
col, MicroSeries
|
|
110
|
-
), f"Got {type(col)} instead of MicroSeries"
|
|
106
|
+
assert isinstance(col, MicroSeries), f"Got {type(col)} instead of MicroSeries"
|
|
111
107
|
assert hasattr(col, "weights")
|
|
112
108
|
assert hasattr(col, "set_weights")
|
|
113
109
|
|
|
@@ -120,9 +116,9 @@ class TestMicroDataFrameSubclassPreservation:
|
|
|
120
116
|
|
|
121
117
|
# Column operations
|
|
122
118
|
result = mdf["a"] + mdf["b"]
|
|
123
|
-
assert isinstance(
|
|
124
|
-
result
|
|
125
|
-
)
|
|
119
|
+
assert isinstance(result, MicroSeries), (
|
|
120
|
+
f"Got {type(result)} instead of MicroSeries"
|
|
121
|
+
)
|
|
126
122
|
assert hasattr(result, "weights")
|
|
127
123
|
|
|
128
124
|
|
|
@@ -186,9 +182,7 @@ class TestCopyOnWriteCompatibility:
|
|
|
186
182
|
|
|
187
183
|
def test_microdataframe_copy_independent(self):
|
|
188
184
|
"""Copying a MicroDataFrame should create an independent copy."""
|
|
189
|
-
mdf = MicroDataFrame(
|
|
190
|
-
{"a": [1, 2, 3]}, weights=np.array([1.0, 2.0, 3.0])
|
|
191
|
-
)
|
|
185
|
+
mdf = MicroDataFrame({"a": [1, 2, 3]}, weights=np.array([1.0, 2.0, 3.0]))
|
|
192
186
|
mdf_copy = mdf.copy()
|
|
193
187
|
|
|
194
188
|
# Modify original
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: microdf-python
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.3
|
|
4
4
|
Summary: Weighted pandas DataFrames and Series for survey microdata
|
|
5
5
|
Author-email: Max Ghenis <max@policyengine.org>
|
|
6
6
|
License: MIT
|
|
@@ -11,12 +11,8 @@ Requires-Dist: numpy
|
|
|
11
11
|
Requires-Dist: pandas
|
|
12
12
|
Provides-Extra: dev
|
|
13
13
|
Requires-Dist: codecov; extra == "dev"
|
|
14
|
-
Requires-Dist:
|
|
15
|
-
Requires-Dist: flake8-pyproject; extra == "dev"
|
|
16
|
-
Requires-Dist: black; extra == "dev"
|
|
14
|
+
Requires-Dist: ruff>=0.9.0; extra == "dev"
|
|
17
15
|
Requires-Dist: docformatter; extra == "dev"
|
|
18
|
-
Requires-Dist: isort; extra == "dev"
|
|
19
|
-
Requires-Dist: linecheck; extra == "dev"
|
|
20
16
|
Requires-Dist: pytest; extra == "dev"
|
|
21
17
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
22
18
|
Requires-Dist: setuptools; extra == "dev"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
microdf/__init__.py,sha256=ldRvhE8t4cD7qlxQ5yLndMnWEUYpDw4m-jCDV_psXkY,319
|
|
2
|
+
microdf/microdataframe.py,sha256=kjID2Zn_8zEp5IG7zc81B9M9QoAb2smMhczL3m8-n1k,33506
|
|
3
|
+
microdf/microseries.py,sha256=fl5GHRRmeehxA-701bbTbz93T7a_BOpjEDmS2BvXSfQ,24775
|
|
4
|
+
microdf/tests/conftest.py,sha256=u-EMyX1-u_nM-YO0RJYCzYHQDXxUI2WQE6GkyJlErqg,150
|
|
5
|
+
microdf/tests/test_microseries_dataframe.py,sha256=WhwxyoFNPQLCvtsIPfAic0Zk71jWedZ6MT0ZaYBPEXk,16186
|
|
6
|
+
microdf/tests/test_pandas3_compatibility.py,sha256=A34Ni_WQ303sSNv-sqv5CGAQp54zj-ZSGAPEBHZslNI,8573
|
|
7
|
+
microdf_python-1.2.3.dist-info/licenses/LICENSE,sha256=uPs-ASYnzlldpf2z8jeRgQFeEH3FLhSuX0rw0OKWoDU,1067
|
|
8
|
+
microdf_python-1.2.3.dist-info/METADATA,sha256=bbTmyHLxi1ThumndS_GMYNlb93WH-PjFSS7h6KJ5j2A,2311
|
|
9
|
+
microdf_python-1.2.3.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
|
|
10
|
+
microdf_python-1.2.3.dist-info/top_level.txt,sha256=T2WFPTygQQMdS3GF8YpZ12DKfMGrspbZ3r7z-e3KfiM,8
|
|
11
|
+
microdf_python-1.2.3.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
microdf/__init__.py,sha256=ldRvhE8t4cD7qlxQ5yLndMnWEUYpDw4m-jCDV_psXkY,319
|
|
2
|
-
microdf/microdataframe.py,sha256=2lZU3FAtVCgKiVD-iD_3xu3NMEEl-7Tbn-T-aOR_ihc,33920
|
|
3
|
-
microdf/microseries.py,sha256=2-UmvJJkxycvqtIW6NfQr1HXFs-LTRctvQr6bkVNYdI,25061
|
|
4
|
-
microdf/tests/conftest.py,sha256=u-EMyX1-u_nM-YO0RJYCzYHQDXxUI2WQE6GkyJlErqg,150
|
|
5
|
-
microdf/tests/test_microseries_dataframe.py,sha256=YidEKYJwwPyCf_ZiAXoc8kydHj4XkZO-0jXQ-olouho,16284
|
|
6
|
-
microdf/tests/test_pandas3_compatibility.py,sha256=p4SZoW59REA5GV84HH9InfCdKQ1nEBGmatnRK84GiGY,8623
|
|
7
|
-
microdf_python-1.2.2.dist-info/licenses/LICENSE,sha256=uPs-ASYnzlldpf2z8jeRgQFeEH3FLhSuX0rw0OKWoDU,1067
|
|
8
|
-
microdf_python-1.2.2.dist-info/METADATA,sha256=o-2nZ_NkEuvOF-BgVG-3oCRr_3X5YdXg15utoUPCfdM,2469
|
|
9
|
-
microdf_python-1.2.2.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
|
|
10
|
-
microdf_python-1.2.2.dist-info/top_level.txt,sha256=T2WFPTygQQMdS3GF8YpZ12DKfMGrspbZ3r7z-e3KfiM,8
|
|
11
|
-
microdf_python-1.2.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|