Skip to content

Commit 03c3ad4

Browse files
authored
Merge pull request #269 from lincc-frameworks/delitem
Implement __delitem__ for NestedFrame
2 parents c136206 + a41a7e4 commit 03c3ad4

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

src/nested_pandas/nestedframe/core.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,10 @@ def __setitem__(self, key, value):
293293
super().__setitem__(key, value)
294294
self._cast_cols_to_nested(struct_list=False)
295295

296+
def __delitem__(self, key):
297+
"""Delete a column or a nested field using dot notation (e.g., del nf['nested.x'])"""
298+
self.drop([key], axis=1, inplace=True)
299+
296300
def add_nested(
297301
self,
298302
obj,
@@ -621,7 +625,10 @@ def drop(
621625
# drop targeted sub-columns for each nested column
622626
for col in nested_cols:
623627
sub_cols = [label.split(".")[1] for label in nested_labels if label.split(".")[0] == col]
624-
self = self.assign(**{f"{col}": self[col].nest.without_field(sub_cols)})
628+
if inplace:
629+
self[col] = self[col].nest.without_field(sub_cols)
630+
else:
631+
self = self.assign(**{f"{col}": self[col].nest.without_field(sub_cols)})
625632

626633
# drop remaining base columns
627634
if len(base_labels) > 0:
@@ -635,7 +642,7 @@ def drop(
635642
errors=errors,
636643
)
637644
else:
638-
return self
645+
return self if not inplace else None
639646
# Otherwise just drop like pandas
640647
return super().drop(
641648
labels=labels,

tests/nested_pandas/nestedframe/test_nestedframe.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,19 +1211,15 @@ def test_scientific_notation():
12111211

12121212
def test_drop():
12131213
"""Test that we can drop nested columns from a NestedFrame"""
1214-
12151214
base = NestedFrame(data={"a": [1, 2, 3], "b": [2, 4, 6]}, index=[0, 1, 2])
1216-
12171215
nested = pd.DataFrame(
12181216
data={"c": [0, 2, 4, 1, 4, 3, 1, 4, 1], "d": [5, 4, 7, 5, 3, 1, 9, 3, 4]},
12191217
index=[0, 0, 0, 1, 1, 1, 2, 2, 2],
12201218
)
1221-
12221219
nested2 = pd.DataFrame(
12231220
data={"e": [0, 2, 4, 1, 4, 3, 1, 4, 1], "f": [5, 4, 7, 5, 3, 1, 9, 3, 4]},
12241221
index=[0, 0, 0, 1, 1, 1, 2, 2, 2],
12251222
)
1226-
12271223
base = base.add_nested(nested, "nested").add_nested(nested2, "nested2")
12281224

12291225
# test axis=0 drop
@@ -1256,6 +1252,31 @@ def test_drop():
12561252
assert "c" not in dropped_multiple.nested.nest.fields
12571253
assert "f" not in dropped_multiple.nested2.nest.fields
12581254

1255+
# Test inplace=True for both base and nested columns
1256+
base2 = base.copy()
1257+
base2.drop(["a", "nested.c"], axis=1, inplace=True)
1258+
assert "a" not in base2.columns
1259+
assert "c" not in base2["nested"].nest.fields
1260+
assert "b" in base2.columns
1261+
assert "d" in base2["nested"].nest.fields
1262+
1263+
# Test inplace=False for both base and nested columns
1264+
base3 = base.copy()
1265+
dropped = base3.drop(["a", "nested.c"], axis=1, inplace=False)
1266+
assert "a" not in dropped.columns
1267+
assert "c" not in dropped["nested"].nest.fields
1268+
assert "b" in dropped.columns
1269+
assert "d" in dropped["nested"].nest.fields
1270+
# Original is unchanged
1271+
assert "a" in base3.columns
1272+
assert "c" in base3["nested"].nest.fields
1273+
1274+
# Test error for missing columns in multi-drop
1275+
with pytest.raises(KeyError):
1276+
base.drop(["not_a_column", "nested.c"], axis=1)
1277+
with pytest.raises(KeyError):
1278+
base.drop(["a", "nested.not_a_field"], axis=1)
1279+
12591280

12601281
def test_eval():
12611282
"""
@@ -1496,3 +1517,25 @@ def test_nest_lists():
14961517
# and that we raise an error if we try to do so.
14971518
with pytest.raises(ValueError):
14981519
ndf.nest_lists(columns=["c", "d"], name="nested")
1520+
1521+
1522+
def test_delitem_base_and_nested():
1523+
"""Test that __delitem__ works for both base and nested columns."""
1524+
base = NestedFrame(data={"a": [1, 2, 3], "b": [2, 4, 6]}, index=[0, 1, 2])
1525+
nested = pd.DataFrame(
1526+
data={"c": [0, 2, 4, 1, 4, 3, 1, 4, 1], "d": [5, 4, 7, 5, 3, 1, 9, 3, 4]},
1527+
index=[0, 0, 0, 1, 1, 1, 2, 2, 2],
1528+
)
1529+
base = base.add_nested(nested, "nested")
1530+
1531+
# Delete a nested field
1532+
del base["nested.c"]
1533+
assert "c" not in base["nested"].nest.fields
1534+
# Delete a base column
1535+
del base["a"]
1536+
assert "a" not in base.columns
1537+
# Deleting a missing column should raise KeyError
1538+
with pytest.raises(KeyError):
1539+
del base["not_a_column"]
1540+
with pytest.raises(KeyError):
1541+
del base["nested.not_a_field"]

0 commit comments

Comments
 (0)