Skip to content

Commit

Permalink
ENH: add inplace-kwarg to df.update
Browse files Browse the repository at this point in the history
  • Loading branch information
h-vetinari committed Aug 23, 2018
1 parent 25e6a21 commit 110ff56
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.24.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ Other Enhancements
- :class:`Series` and :class:`DataFrame` now support :class:`Iterable` in constructor (:issue:`2193`)
- :class:`DatetimeIndex` gained :attr:`DatetimeIndex.timetz` attribute. Returns local time with timezone information. (:issue:`21358`)
- :class:`Resampler` now is iterable like :class:`GroupBy` (:issue:`15314`).
- :meth:`DataFrame.update` has gained an ``inplace``-kwarg, which defaults to True (same behavior as before). (:issue:`21858`)
- :ref:`Series.resample` and :ref:`DataFrame.resample` have gained the :meth:`Resampler.quantile` (:issue:`15023`).

.. _whatsnew_0240.api_breaking:
Expand Down
21 changes: 17 additions & 4 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -5078,7 +5078,7 @@ def combiner(x, y, needs_i8_conversion=False):
return self.combine(other, combiner, overwrite=False)

def update(self, other, join='left', overwrite=True, filter_func=None,
raise_conflict=False):
raise_conflict=False, inplace=True):
"""
Modify in place using non-NA values from another DataFrame.
Expand Down Expand Up @@ -5108,6 +5108,11 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
raise_conflict : bool, default False
If True, will raise a ValueError if the DataFrame and `other`
both contain non-NA data in the same place.
inplace : bool, default True
If True, updates the DataFrame inplace. If False, returns a new
DataFrame.
.. versionadded:: 0.24.0
Raises
------
Expand Down Expand Up @@ -5189,8 +5194,13 @@ def update(self, other, join='left', overwrite=True, filter_func=None,

other = other.reindex_like(self)

for col in self.columns:
this = self[col].values
if inplace:
frame = self
else:
frame = self.copy()

for col in frame.columns:
this = frame[col].values
that = other[col].values
if filter_func is not None:
with np.errstate(all='ignore'):
Expand All @@ -5211,7 +5221,10 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
if mask.all():
continue

self[col] = expressions.where(mask, this, that)
frame[col] = expressions.where(mask, this, that)

if not inplace:
return frame

# ----------------------------------------------------------------------
# Data reshaping
Expand Down
15 changes: 12 additions & 3 deletions pandas/tests/frame/test_combine_concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from datetime import datetime

import pytest

import numpy as np
from numpy import nan

Expand Down Expand Up @@ -198,7 +200,8 @@ def test_append_dtypes(self):
expected = DataFrame({'bar': Series([Timestamp('20130101'), 1])})
assert_frame_equal(result, expected)

def test_update(self):
@pytest.mark.parametrize('inplace', [True, False])
def test_update(self, inplace):
df = DataFrame([[1.5, nan, 3.],
[1.5, nan, 3.],
[1.5, nan, 3],
Expand All @@ -207,13 +210,19 @@ def test_update(self):
other = DataFrame([[3.6, 2., np.nan],
[np.nan, np.nan, 7]], index=[1, 3])

df.update(other)
if inplace:
df.update(other, inplace=inplace)
result = df
else:
orig = df.copy()
result = df.update(other, inplace=inplace)
assert_frame_equal(df, orig)

expected = DataFrame([[1.5, nan, 3],
[3.6, 2, 3],
[1.5, nan, 3],
[1.5, nan, 7.]])
assert_frame_equal(df, expected)
assert_frame_equal(result, expected)

def test_update_dtypes(self):

Expand Down

0 comments on commit 110ff56

Please sign in to comment.