Skip to content

Commit ccb087e

Browse files
phoflim-vinicius
authored and
im-vinicius
committed
CoW: Delay copy when setting Series or Frame with isetitem (pandas-dev#52051)
1 parent d93006b commit ccb087e

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
@@ -3913,6 +3913,7 @@ def isetitem(self, loc, value) -> None:
39133913
In cases where ``frame.columns`` is unique, this is equivalent to
39143914
``frame[frame.columns[i]] = value``.
39153915
"""
3916+
using_cow = using_copy_on_write()
39163917
if isinstance(value, DataFrame):
39173918
if is_integer(loc):
39183919
loc = [loc]
@@ -3924,12 +3925,14 @@ def isetitem(self, loc, value) -> None:
39243925
)
39253926

39263927
for i, idx in enumerate(loc):
3927-
arraylike, _ = self._sanitize_column(value.iloc[:, i])
3928-
self._iset_item_mgr(idx, arraylike, inplace=False)
3928+
arraylike, refs = self._sanitize_column(
3929+
value.iloc[:, i], using_cow=using_cow
3930+
)
3931+
self._iset_item_mgr(idx, arraylike, inplace=False, refs=refs)
39293932
return
39303933

3931-
arraylike, _ = self._sanitize_column(value)
3932-
self._iset_item_mgr(loc, arraylike, inplace=False)
3934+
arraylike, refs = self._sanitize_column(value, using_cow=using_cow)
3935+
self._iset_item_mgr(loc, arraylike, inplace=False, refs=refs)
39333936

39343937
def __setitem__(self, key, value):
39353938
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)