Skip to content

Commit 9316d3e

Browse files
author
dkamm
committed
BUG: wrap all supported inplace methods to avoid making a copy (#12962)
1 parent 6630c4e commit 9316d3e

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

pandas/core/ops.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,10 @@ def add_special_arithmetic_methods(cls, arith_method=None,
186186
arith_method : function (optional)
187187
factory for special arithmetic methods, with op string:
188188
f(op, name, str_rep, default_axis=None, fill_zeros=None, **eval_kwargs)
189-
comp_method : function, optional,
189+
comp_method : function (optional)
190190
factory for rich comparison - signature: f(op, name, str_rep)
191+
bool_method : function (optional)
192+
factory for boolean methods - signature: f(op, name, str_rep)
191193
use_numexpr : bool, default True
192194
whether to accelerate with numexpr, defaults to True
193195
force : bool, default False
@@ -234,9 +236,16 @@ def f(self, other):
234236
__isub__=_wrap_inplace_method(new_methods["__sub__"]),
235237
__imul__=_wrap_inplace_method(new_methods["__mul__"]),
236238
__itruediv__=_wrap_inplace_method(new_methods["__truediv__"]),
237-
__ipow__=_wrap_inplace_method(new_methods["__pow__"]), ))
239+
__ifloordiv__=_wrap_inplace_method(new_methods["__floordiv__"]),
240+
__imod__=_wrap_inplace_method(new_methods["__mod__"]),
241+
__ipow__=_wrap_inplace_method(new_methods["__pow__"])))
238242
if not compat.PY3:
239-
new_methods["__idiv__"] = new_methods["__div__"]
243+
new_methods["__idiv__"] = _wrap_inplace_method(new_methods["__div__"])
244+
if bool_method:
245+
new_methods.update(
246+
dict(__iand__=_wrap_inplace_method(new_methods["__and__"]),
247+
__ior__=_wrap_inplace_method(new_methods["__or__"]),
248+
__ixor__=_wrap_inplace_method(new_methods["__xor__"])))
240249

241250
add_methods(cls, new_methods=new_methods, force=force, select=select,
242251
exclude=exclude)

pandas/tests/frame/test_operators.py

+27
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,33 @@ def test_inplace_ops_identity(self):
11611161
assert_frame_equal(df2, expected)
11621162
assert df._data is df2._data
11631163

1164+
# no id change
1165+
df = DataFrame({'a': [1., 2., 3.]})
1166+
expected = id(df)
1167+
df += 2.
1168+
assert id(df) == expected
1169+
df -= 2.
1170+
assert id(df) == expected
1171+
df *= 2.
1172+
assert id(df) == expected
1173+
df /= 2.
1174+
assert id(df) == expected
1175+
df **= 2.
1176+
assert id(df) == expected
1177+
df //= 2.
1178+
assert id(df) == expected
1179+
df %= 2.
1180+
assert id(df) == expected
1181+
1182+
df = DataFrame({'a': [1, 0, 5]})
1183+
expected = id(df)
1184+
df &= 1
1185+
assert id(df) == expected
1186+
df |= 1
1187+
assert id(df) == expected
1188+
df ^= 1
1189+
assert id(df) == expected
1190+
11641191
def test_alignment_non_pandas(self):
11651192
index = ['A', 'B', 'C']
11661193
columns = ['X', 'Y', 'Z']

0 commit comments

Comments
 (0)