Skip to content

Commit b99d7c0

Browse files
phofltopper-123
authored andcommitted
CoW: Delay copy when setting Series or Frame with isetitem (pandas-dev#52051)
1 parent d784cc1 commit b99d7c0

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

pandas/core/frame.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -3929,6 +3929,7 @@ def isetitem(self, loc, value) -> None:
39293929
In cases where ``frame.columns`` is unique, this is equivalent to
39303930
``frame[frame.columns[i]] = value``.
39313931
"""
3932+
using_cow = using_copy_on_write()
39323933
if isinstance(value, DataFrame):
39333934
if is_integer(loc):
39343935
loc = [loc]
@@ -3940,12 +3941,14 @@ def isetitem(self, loc, value) -> None:
39403941
)
39413942

39423943
for i, idx in enumerate(loc):
3943-
arraylike, _ = self._sanitize_column(value.iloc[:, i])
3944-
self._iset_item_mgr(idx, arraylike, inplace=False)
3944+
arraylike, refs = self._sanitize_column(
3945+
value.iloc[:, i], using_cow=using_cow
3946+
)
3947+
self._iset_item_mgr(idx, arraylike, inplace=False, refs=refs)
39453948
return
39463949

3947-
arraylike, _ = self._sanitize_column(value)
3948-
self._iset_item_mgr(loc, arraylike, inplace=False)
3950+
arraylike, refs = self._sanitize_column(value, using_cow=using_cow)
3951+
self._iset_item_mgr(loc, arraylike, inplace=False, refs=refs)
39493952

39503953
def __setitem__(self, key, value):
39513954
if not PYPY and using_copy_on_write():

pandas/tests/copy_view/test_methods.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -1521,8 +1521,8 @@ def test_isetitem_series(using_copy_on_write, dtype):
15211521
df.isetitem(0, ser)
15221522

15231523
if using_copy_on_write:
1524-
# TODO(CoW) this can share memory
1525-
assert not np.shares_memory(get_array(df, "a"), get_array(ser))
1524+
assert np.shares_memory(get_array(df, "a"), get_array(ser))
1525+
assert not df._mgr._has_no_reference(0)
15261526

15271527
# mutating dataframe doesn't update series
15281528
df.loc[0, "a"] = 0
@@ -1538,6 +1538,23 @@ def test_isetitem_series(using_copy_on_write, dtype):
15381538
tm.assert_frame_equal(df, expected)
15391539

15401540

1541+
def test_isetitem_frame(using_copy_on_write):
1542+
df = DataFrame({"a": [1, 2, 3], "b": 1, "c": 2})
1543+
rhs = DataFrame({"a": [4, 5, 6], "b": 2})
1544+
df.isetitem([0, 1], rhs)
1545+
if using_copy_on_write:
1546+
assert np.shares_memory(get_array(df, "a"), get_array(rhs, "a"))
1547+
assert np.shares_memory(get_array(df, "b"), get_array(rhs, "b"))
1548+
assert not df._mgr._has_no_reference(0)
1549+
else:
1550+
assert not np.shares_memory(get_array(df, "a"), get_array(rhs, "a"))
1551+
assert not np.shares_memory(get_array(df, "b"), get_array(rhs, "b"))
1552+
expected = df.copy()
1553+
rhs.iloc[0, 0] = 100
1554+
rhs.iloc[0, 1] = 100
1555+
tm.assert_frame_equal(df, expected)
1556+
1557+
15411558
@pytest.mark.parametrize("key", ["a", ["a"]])
15421559
def test_get(using_copy_on_write, key):
15431560
df = DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})

0 commit comments

Comments
 (0)