Skip to content

Commit e50b5fe

Browse files
h-vetinarijreback
authored andcommitted
API/DEPR: replace "raise_conflict" with "errors" for df.update (pandas-dev#23657)
1 parent ee5e79f commit e50b5fe

File tree

5 files changed

+95
-27
lines changed

5 files changed

+95
-27
lines changed

doc/source/whatsnew/v0.24.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,7 @@ Deprecations
10221022
- The ``fastpath`` keyword of the different Index constructors is deprecated (:issue:`23110`).
10231023
- :meth:`Timestamp.tz_localize`, :meth:`DatetimeIndex.tz_localize`, and :meth:`Series.tz_localize` have deprecated the ``errors`` argument in favor of the ``nonexistent`` argument (:issue:`8917`)
10241024
- The class ``FrozenNDArray`` has been deprecated. When unpickling, ``FrozenNDArray`` will be unpickled to ``np.ndarray`` once this class is removed (:issue:`9031`)
1025+
- The methods :meth:`DataFrame.update` and :meth:`Panel.update` have deprecated the ``raise_conflict=False|True`` keyword in favor of ``errors='ignore'|'raise'`` (:issue:`23585`)
10251026
- Deprecated the `nthreads` keyword of :func:`pandas.read_feather` in favor of
10261027
`use_threads` to reflect the changes in pyarrow 0.11.0. (:issue:`23053`)
10271028
- :func:`pandas.read_excel` has deprecated accepting ``usecols`` as an integer. Please pass in a list of ints from 0 to ``usecols`` inclusive instead (:issue:`23527`)

pandas/core/frame.py

+22-6
Original file line numberDiff line numberDiff line change
@@ -5213,8 +5213,10 @@ def combiner(x, y):
52135213

52145214
return self.combine(other, combiner, overwrite=False)
52155215

5216+
@deprecate_kwarg(old_arg_name='raise_conflict', new_arg_name='errors',
5217+
mapping={False: 'ignore', True: 'raise'})
52165218
def update(self, other, join='left', overwrite=True, filter_func=None,
5217-
raise_conflict=False):
5219+
errors='ignore'):
52185220
"""
52195221
Modify in place using non-NA values from another DataFrame.
52205222
@@ -5238,17 +5240,28 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
52385240
* False: only update values that are NA in
52395241
the original DataFrame.
52405242
5241-
filter_func : callable(1d-array) -> boolean 1d-array, optional
5243+
filter_func : callable(1d-array) -> bool 1d-array, optional
52425244
Can choose to replace values other than NA. Return True for values
52435245
that should be updated.
5244-
raise_conflict : bool, default False
5245-
If True, will raise a ValueError if the DataFrame and `other`
5246+
errors : {'raise', 'ignore'}, default 'ignore'
5247+
If 'raise', will raise a ValueError if the DataFrame and `other`
52465248
both contain non-NA data in the same place.
52475249
5250+
.. versionchanged :: 0.24.0
5251+
Changed from `raise_conflict=False|True`
5252+
to `errors='ignore'|'raise'`.
5253+
5254+
Returns
5255+
-------
5256+
None : method directly changes calling object
5257+
52485258
Raises
52495259
------
52505260
ValueError
5251-
When `raise_conflict` is True and there's overlapping non-NA data.
5261+
* When `errors='raise'` and there's overlapping non-NA data.
5262+
* When `errors` is not either `'ignore'` or `'raise'`
5263+
NotImplementedError
5264+
* If `join != 'left'`
52525265
52535266
See Also
52545267
--------
@@ -5319,6 +5332,9 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
53195332
# TODO: Support other joins
53205333
if join != 'left': # pragma: no cover
53215334
raise NotImplementedError("Only left join is supported")
5335+
if errors not in ['ignore', 'raise']:
5336+
raise ValueError("The parameter errors must be either "
5337+
"'ignore' or 'raise'")
53225338

53235339
if not isinstance(other, DataFrame):
53245340
other = DataFrame(other)
@@ -5332,7 +5348,7 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
53325348
with np.errstate(all='ignore'):
53335349
mask = ~filter_func(this) | isna(that)
53345350
else:
5335-
if raise_conflict:
5351+
if errors == 'raise':
53365352
mask_this = notna(that)
53375353
mask_that = notna(this)
53385354
if any(mask_this & mask_that):

pandas/core/panel.py

+33-16
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
create_block_manager_from_blocks)
3333
from pandas.core.series import Series
3434
from pandas.core.reshape.util import cartesian_product
35-
from pandas.util._decorators import Appender, Substitution
35+
from pandas.util._decorators import Appender, Substitution, deprecate_kwarg
3636
from pandas.util._validators import validate_axis_style_args
3737

3838
_shared_doc_kwargs = dict(
@@ -1235,7 +1235,12 @@ def reindex(self, *args, **kwargs):
12351235
kwargs.update(axes)
12361236
kwargs.pop('axis', None)
12371237
kwargs.pop('labels', None)
1238-
return super(Panel, self).reindex(**kwargs)
1238+
1239+
with warnings.catch_warnings():
1240+
warnings.simplefilter("ignore", FutureWarning)
1241+
# do not warn about constructing Panel when reindexing
1242+
result = super(Panel, self).reindex(**kwargs)
1243+
return result
12391244

12401245
@Substitution(**_shared_doc_kwargs)
12411246
@Appender(NDFrame.rename.__doc__)
@@ -1377,25 +1382,37 @@ def join(self, other, how='left', lsuffix='', rsuffix=''):
13771382
return concat([self] + list(other), axis=0, join=how,
13781383
join_axes=join_axes, verify_integrity=True)
13791384

1385+
@deprecate_kwarg(old_arg_name='raise_conflict', new_arg_name='errors',
1386+
mapping={False: 'ignore', True: 'raise'})
13801387
def update(self, other, join='left', overwrite=True, filter_func=None,
1381-
raise_conflict=False):
1388+
errors='ignore'):
13821389
"""
1383-
Modify Panel in place using non-NA values from passed
1384-
Panel, or object coercible to Panel. Aligns on items
1390+
Modify Panel in place using non-NA values from other Panel.
1391+
1392+
May also use object coercible to Panel. Will align on items.
13851393
13861394
Parameters
13871395
----------
13881396
other : Panel, or object coercible to Panel
1389-
join : How to join individual DataFrames
1390-
{'left', 'right', 'outer', 'inner'}, default 'left'
1391-
overwrite : boolean, default True
1392-
If True then overwrite values for common keys in the calling panel
1393-
filter_func : callable(1d-array) -> 1d-array<boolean>, default None
1397+
The object from which the caller will be udpated.
1398+
join : {'left', 'right', 'outer', 'inner'}, default 'left'
1399+
How individual DataFrames are joined.
1400+
overwrite : bool, default True
1401+
If True then overwrite values for common keys in the calling Panel.
1402+
filter_func : callable(1d-array) -> 1d-array<bool>, default None
13941403
Can choose to replace values other than NA. Return True for values
1395-
that should be updated
1396-
raise_conflict : bool
1397-
If True, will raise an error if a DataFrame and other both
1398-
contain data in the same place.
1404+
that should be updated.
1405+
errors : {'raise', 'ignore'}, default 'ignore'
1406+
If 'raise', will raise an error if a DataFrame and other both.
1407+
1408+
.. versionchanged :: 0.24.0
1409+
Changed from `raise_conflict=False|True`
1410+
to `errors='ignore'|'raise'`.
1411+
1412+
See Also
1413+
--------
1414+
DataFrame.update : Similar method for DataFrames.
1415+
dict.update : Similar method for dictionaries.
13991416
"""
14001417

14011418
if not isinstance(other, self._constructor):
@@ -1406,8 +1423,8 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
14061423
other = other.reindex(**{axis_name: axis_values})
14071424

14081425
for frame in axis_values:
1409-
self[frame].update(other[frame], join, overwrite, filter_func,
1410-
raise_conflict)
1426+
self[frame].update(other[frame], join=join, overwrite=overwrite,
1427+
filter_func=filter_func, errors=errors)
14111428

14121429
def _get_join_index(self, other, how):
14131430
if how == 'left':

pandas/tests/frame/test_combine_concat.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,17 @@ def test_update_filtered(self):
313313
[1.5, nan, 7.]])
314314
assert_frame_equal(df, expected)
315315

316-
def test_update_raise(self):
316+
@pytest.mark.parametrize('bad_kwarg, exception, msg', [
317+
# errors must be 'ignore' or 'raise'
318+
({'errors': 'something'}, ValueError, 'The parameter errors must.*'),
319+
({'join': 'inner'}, NotImplementedError, 'Only left join is supported')
320+
])
321+
def test_update_raise_bad_parameter(self, bad_kwarg, exception, msg):
322+
df = DataFrame([[1.5, 1, 3.]])
323+
with pytest.raises(exception, match=msg):
324+
df.update(df, **bad_kwarg)
325+
326+
def test_update_raise_on_overlap(self):
317327
df = DataFrame([[1.5, 1, 3.],
318328
[1.5, nan, 3.],
319329
[1.5, nan, 3],
@@ -322,7 +332,14 @@ def test_update_raise(self):
322332
other = DataFrame([[2., nan],
323333
[nan, 7]], index=[1, 3], columns=[1, 2])
324334
with pytest.raises(ValueError, match="Data overlaps"):
325-
df.update(other, raise_conflict=True)
335+
df.update(other, errors='raise')
336+
337+
@pytest.mark.parametrize('raise_conflict', [True, False])
338+
def test_update_deprecation(self, raise_conflict):
339+
df = DataFrame([[1.5, 1, 3.]])
340+
other = DataFrame()
341+
with tm.assert_produces_warning(FutureWarning):
342+
df.update(other, raise_conflict=raise_conflict)
326343

327344
def test_update_from_non_df(self):
328345
d = {'a': Series([1, 2, 3, 4]), 'b': Series([5, 6, 7, 8])}

pandas/tests/test_panel.py

+20-3
Original file line numberDiff line numberDiff line change
@@ -2341,16 +2341,33 @@ def test_update_filtered(self):
23412341

23422342
assert_panel_equal(pan, expected)
23432343

2344-
def test_update_raise(self):
2344+
@pytest.mark.parametrize('bad_kwarg, exception, msg', [
2345+
# errors must be 'ignore' or 'raise'
2346+
({'errors': 'something'}, ValueError, 'The parameter errors must.*'),
2347+
({'join': 'inner'}, NotImplementedError, 'Only left join is supported')
2348+
])
2349+
def test_update_raise_bad_parameter(self, bad_kwarg, exception, msg):
2350+
pan = Panel([[[1.5, np.nan, 3.]]])
2351+
with pytest.raises(exception, match=msg):
2352+
pan.update(pan, **bad_kwarg)
2353+
2354+
def test_update_raise_on_overlap(self):
23452355
pan = Panel([[[1.5, np.nan, 3.], [1.5, np.nan, 3.],
23462356
[1.5, np.nan, 3.],
23472357
[1.5, np.nan, 3.]],
23482358
[[1.5, np.nan, 3.], [1.5, np.nan, 3.],
23492359
[1.5, np.nan, 3.],
23502360
[1.5, np.nan, 3.]]])
23512361

2352-
pytest.raises(Exception, pan.update, *(pan, ),
2353-
**{'raise_conflict': True})
2362+
with pytest.raises(ValueError, match='Data overlaps'):
2363+
pan.update(pan, errors='raise')
2364+
2365+
@pytest.mark.parametrize('raise_conflict', [True, False])
2366+
def test_update_deprecation(self, raise_conflict):
2367+
pan = Panel([[[1.5, np.nan, 3.]]])
2368+
other = Panel([[[]]])
2369+
with tm.assert_produces_warning(FutureWarning):
2370+
pan.update(other, raise_conflict=raise_conflict)
23542371

23552372
def test_all_any(self):
23562373
assert (self.panel.all(axis=0).values == nanall(

0 commit comments

Comments
 (0)