Skip to content

Commit efa878d

Browse files
phoflYi Wei
authored and
Yi Wei
committed
CoW: Delay copy when enlarging df with loc (pandas-dev#52062)
1 parent 88fff50 commit efa878d

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

pandas/core/indexing.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,7 +1979,10 @@ def _setitem_with_indexer_frame_value(self, indexer, value: DataFrame, name: str
19791979
if item in value:
19801980
sub_indexer[1] = item
19811981
val = self._align_series(
1982-
tuple(sub_indexer), value[item], multiindex_indexer
1982+
tuple(sub_indexer),
1983+
value[item],
1984+
multiindex_indexer,
1985+
using_cow=using_copy_on_write(),
19831986
)
19841987
else:
19851988
val = np.nan
@@ -2185,7 +2188,13 @@ def _ensure_iterable_column_indexer(self, column_indexer):
21852188
ilocs = column_indexer
21862189
return ilocs
21872190

2188-
def _align_series(self, indexer, ser: Series, multiindex_indexer: bool = False):
2191+
def _align_series(
2192+
self,
2193+
indexer,
2194+
ser: Series,
2195+
multiindex_indexer: bool = False,
2196+
using_cow: bool = False,
2197+
):
21892198
"""
21902199
Parameters
21912200
----------
@@ -2254,6 +2263,8 @@ def ravel(i):
22542263
else:
22552264
new_ix = Index(new_ix)
22562265
if ser.index.equals(new_ix):
2266+
if using_cow:
2267+
return ser
22572268
return ser._values.copy()
22582269

22592270
return ser.reindex(new_ix)._values

pandas/tests/copy_view/test_indexing.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,3 +1073,19 @@ def test_series_midx_tuples_slice(using_copy_on_write):
10731073
index=pd.MultiIndex.from_tuples([((1, 2), 3), ((1, 2), 4), ((2, 3), 4)]),
10741074
)
10751075
tm.assert_series_equal(ser, expected)
1076+
1077+
1078+
def test_loc_enlarging_with_dataframe(using_copy_on_write):
1079+
df = DataFrame({"a": [1, 2, 3]})
1080+
rhs = DataFrame({"b": [1, 2, 3], "c": [4, 5, 6]})
1081+
rhs_orig = rhs.copy()
1082+
df.loc[:, ["b", "c"]] = rhs
1083+
if using_copy_on_write:
1084+
assert np.shares_memory(get_array(df, "b"), get_array(rhs, "b"))
1085+
assert np.shares_memory(get_array(df, "c"), get_array(rhs, "c"))
1086+
assert not df._mgr._has_no_reference(1)
1087+
else:
1088+
assert not np.shares_memory(get_array(df, "b"), get_array(rhs, "b"))
1089+
1090+
df.iloc[0, 1] = 100
1091+
tm.assert_frame_equal(rhs, rhs_orig)

0 commit comments

Comments
 (0)