Skip to content

Commit 8f6a72b

Browse files
committed
DEPR: deprecate raise_on_error in .where/.mask in favor of errors=
closes #14968
1 parent 2ff1241 commit 8f6a72b

File tree

12 files changed

+108
-68
lines changed

12 files changed

+108
-68
lines changed

Diff for: doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ Deprecations
666666
- ``cdate_range`` has been deprecated in favor of :func:`bdate_range`, which has gained ``weekmask`` and ``holidays`` parameters for building custom frequency date ranges. See the :ref:`documentation <timeseries.custom-freq-ranges>` for more details (:issue:`17596`)
667667
- passing ``categories`` or ``ordered`` kwargs to :func:`Series.astype` is deprecated, in favor of passing a :ref:`CategoricalDtype <whatsnew_0210.enhancements.categorical_dtype>` (:issue:`17636`)
668668
- Passing a non-existant column in ``.to_excel(..., columns=)`` is deprecated and will raise a ``KeyError`` in the future (:issue:`17295`)
669+
- ``raise_on_error`` parameter to :func:`Series.where`, :func:`Series.mask`, :func:`DataFrame.where`, :func:`DataFrame.mask` is deprecated, in favor of ``errors=`` (:issue:`14968`)
669670

670671
.. _whatsnew_0210.deprecations.argmin_min:
671672

Diff for: pandas/core/computation/expressions.py

+14-24
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def set_numexpr_threads(n=None):
5656
ne.set_num_threads(n)
5757

5858

59-
def _evaluate_standard(op, op_str, a, b, raise_on_error=True, **eval_kwargs):
59+
def _evaluate_standard(op, op_str, a, b, **eval_kwargs):
6060
""" standard evaluation """
6161
if _TEST_MODE:
6262
_store_test_result(False)
@@ -89,7 +89,7 @@ def _can_use_numexpr(op, op_str, a, b, dtype_check):
8989
return False
9090

9191

92-
def _evaluate_numexpr(op, op_str, a, b, raise_on_error=False, truediv=True,
92+
def _evaluate_numexpr(op, op_str, a, b, truediv=True,
9393
reversed=False, **eval_kwargs):
9494
result = None
9595

@@ -111,25 +111,22 @@ def _evaluate_numexpr(op, op_str, a, b, raise_on_error=False, truediv=True,
111111
except ValueError as detail:
112112
if 'unknown type object' in str(detail):
113113
pass
114-
except Exception as detail:
115-
if raise_on_error:
116-
raise
117114

118115
if _TEST_MODE:
119116
_store_test_result(result is not None)
120117

121118
if result is None:
122-
result = _evaluate_standard(op, op_str, a, b, raise_on_error)
119+
result = _evaluate_standard(op, op_str, a, b)
123120

124121
return result
125122

126123

127-
def _where_standard(cond, a, b, raise_on_error=True):
124+
def _where_standard(cond, a, b):
128125
return np.where(_values_from_object(cond), _values_from_object(a),
129126
_values_from_object(b))
130127

131128

132-
def _where_numexpr(cond, a, b, raise_on_error=False):
129+
def _where_numexpr(cond, a, b):
133130
result = None
134131

135132
if _can_use_numexpr(None, 'where', a, b, 'where'):
@@ -147,11 +144,10 @@ def _where_numexpr(cond, a, b, raise_on_error=False):
147144
if 'unknown type object' in str(detail):
148145
pass
149146
except Exception as detail:
150-
if raise_on_error:
151-
raise TypeError(str(detail))
147+
raise TypeError(str(detail))
152148

153149
if result is None:
154-
result = _where_standard(cond, a, b, raise_on_error)
150+
result = _where_standard(cond, a, b)
155151

156152
return result
157153

@@ -189,7 +185,7 @@ def _bool_arith_check(op_str, a, b, not_allowed=frozenset(('/', '//', '**')),
189185
return True
190186

191187

192-
def evaluate(op, op_str, a, b, raise_on_error=False, use_numexpr=True,
188+
def evaluate(op, op_str, a, b, use_numexpr=True,
193189
**eval_kwargs):
194190
""" evaluate and return the expression of the op on a and b
195191
@@ -200,19 +196,16 @@ def evaluate(op, op_str, a, b, raise_on_error=False, use_numexpr=True,
200196
op_str: the string version of the op
201197
a : left operand
202198
b : right operand
203-
raise_on_error : pass the error to the higher level if indicated
204-
(default is False), otherwise evaluate the op with and
205-
return the results
206199
use_numexpr : whether to try to use numexpr (default True)
207200
"""
201+
208202
use_numexpr = use_numexpr and _bool_arith_check(op_str, a, b)
209203
if use_numexpr:
210-
return _evaluate(op, op_str, a, b, raise_on_error=raise_on_error,
211-
**eval_kwargs)
212-
return _evaluate_standard(op, op_str, a, b, raise_on_error=raise_on_error)
204+
return _evaluate(op, op_str, a, b, **eval_kwargs)
205+
return _evaluate_standard(op, op_str, a, b)
213206

214207

215-
def where(cond, a, b, raise_on_error=False, use_numexpr=True):
208+
def where(cond, a, b, use_numexpr=True):
216209
""" evaluate the where condition cond on a and b
217210
218211
Parameters
@@ -221,15 +214,12 @@ def where(cond, a, b, raise_on_error=False, use_numexpr=True):
221214
cond : a boolean array
222215
a : return if cond is True
223216
b : return if cond is False
224-
raise_on_error : pass the error to the higher level if indicated
225-
(default is False), otherwise evaluate the op with and
226-
return the results
227217
use_numexpr : whether to try to use numexpr (default True)
228218
"""
229219

230220
if use_numexpr:
231-
return _where(cond, a, b, raise_on_error=raise_on_error)
232-
return _where_standard(cond, a, b, raise_on_error=raise_on_error)
221+
return _where(cond, a, b)
222+
return _where_standard(cond, a, b)
233223

234224

235225
def set_test_mode(v=True):

Diff for: pandas/core/frame.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -3832,9 +3832,9 @@ def _combine_match_columns(self, other, func, level=None,
38323832
try_cast=try_cast)
38333833
return self._constructor(new_data)
38343834

3835-
def _combine_const(self, other, func, raise_on_error=True, try_cast=True):
3835+
def _combine_const(self, other, func, errors='raise', try_cast=True):
38363836
new_data = self._data.eval(func=func, other=other,
3837-
raise_on_error=raise_on_error,
3837+
errors=errors,
38383838
try_cast=try_cast)
38393839
return self._constructor(new_data)
38403840

@@ -4005,8 +4005,7 @@ def combiner(x, y, needs_i8_conversion=False):
40054005
else:
40064006
mask = isna(x_values)
40074007

4008-
return expressions.where(mask, y_values, x_values,
4009-
raise_on_error=True)
4008+
return expressions.where(mask, y_values, x_values)
40104009

40114010
return self.combine(other, combiner, overwrite=False)
40124011

@@ -4061,8 +4060,7 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
40614060
if mask.all():
40624061
continue
40634062

4064-
self[col] = expressions.where(mask, this, that,
4065-
raise_on_error=True)
4063+
self[col] = expressions.where(mask, this, that)
40664064

40674065
# ----------------------------------------------------------------------
40684066
# Misc methods

Diff for: pandas/core/generic.py

+35-7
Original file line numberDiff line numberDiff line change
@@ -5748,7 +5748,7 @@ def _align_series(self, other, join='outer', axis=None, level=None,
57485748
return left.__finalize__(self), right.__finalize__(other)
57495749

57505750
def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
5751-
try_cast=False, raise_on_error=True):
5751+
errors='raise', try_cast=False):
57525752
"""
57535753
Equivalent to public method `where`, except that `other` is not
57545754
applied as a function even if callable. Used in __setitem__.
@@ -5877,7 +5877,7 @@ def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
58775877

58785878
else:
58795879
new_data = self._data.where(other=other, cond=cond, align=align,
5880-
raise_on_error=raise_on_error,
5880+
errors=errors,
58815881
try_cast=try_cast, axis=block_axis,
58825882
transpose=self._AXIS_REVERSED)
58835883

@@ -5914,12 +5914,18 @@ def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
59145914
Whether to perform the operation in place on the data
59155915
axis : alignment axis if needed, default None
59165916
level : alignment level if needed, default None
5917+
errors : str, {'raise', 'ignore'}, default 'raise'
5918+
- ``raise`` : allow exceptions to be raised
5919+
- ``ignore`` : suppress exceptions. On error return original object
5920+
59175921
try_cast : boolean, default False
59185922
try to cast the result back to the input type (if possible),
59195923
raise_on_error : boolean, default True
59205924
Whether to raise on invalid data types (e.g. trying to where on
59215925
strings)
59225926
5927+
.. deprecated:: 0.21.0
5928+
59235929
Returns
59245930
-------
59255931
wh : same type as caller
@@ -5995,24 +6001,46 @@ def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
59956001
cond_rev="False", name='where',
59966002
name_other='mask'))
59976003
def where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
5998-
try_cast=False, raise_on_error=True):
6004+
errors='raise', try_cast=False, raise_on_error=None):
6005+
6006+
if raise_on_error is not None:
6007+
warnings.warn(
6008+
"raise_on_error is deprecated in "
6009+
"favor of errors='raise|ignore'",
6010+
FutureWarning, stacklevel=2)
6011+
6012+
if raise_on_error:
6013+
errors = 'raise'
6014+
else:
6015+
errors = 'ignore'
59996016

60006017
other = com._apply_if_callable(other, self)
6001-
return self._where(cond, other, inplace, axis, level, try_cast,
6002-
raise_on_error)
6018+
return self._where(cond, other, inplace, axis, level,
6019+
errors=errors, try_cast=try_cast)
60036020

60046021
@Appender(_shared_docs['where'] % dict(_shared_doc_kwargs, cond="False",
60056022
cond_rev="True", name='mask',
60066023
name_other='where'))
60076024
def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None,
6008-
try_cast=False, raise_on_error=True):
6025+
errors='raise', try_cast=False, raise_on_error=None):
6026+
6027+
if raise_on_error is not None:
6028+
warnings.warn(
6029+
"raise_on_error is deprecated in "
6030+
"favor of errors='raise|ignore'",
6031+
FutureWarning, stacklevel=2)
6032+
6033+
if raise_on_error:
6034+
errors = 'raise'
6035+
else:
6036+
errors = 'ignore'
60096037

60106038
inplace = validate_bool_kwarg(inplace, 'inplace')
60116039
cond = com._apply_if_callable(cond, self)
60126040

60136041
return self.where(~cond, other=other, inplace=inplace, axis=axis,
60146042
level=level, try_cast=try_cast,
6015-
raise_on_error=raise_on_error)
6043+
errors=errors)
60166044

60176045
_shared_docs['shift'] = ("""
60186046
Shift index by desired number of periods with an optional time freq

Diff for: pandas/core/internals.py

+31-16
Original file line numberDiff line numberDiff line change
@@ -532,10 +532,20 @@ def astype(self, dtype, copy=False, errors='raise', values=None, **kwargs):
532532
**kwargs)
533533

534534
def _astype(self, dtype, copy=False, errors='raise', values=None,
535-
klass=None, mgr=None, raise_on_error=False, **kwargs):
535+
klass=None, mgr=None, **kwargs):
536536
"""
537-
Coerce to the new type (if copy=True, return a new copy)
538-
raise on an except if raise == True
537+
Coerce to the new type
538+
539+
dtype : str, dtype convertible
540+
copy : boolean, default False
541+
copy if indicated
542+
errors : str, {'raise', 'ignore'}, default 'ignore'
543+
- ``raise`` : allow exceptions to be raised
544+
- ``ignore`` : suppress exceptions. On error return original object
545+
546+
values :
547+
klass :
548+
mgr :
539549
"""
540550
errors_legal_values = ('raise', 'ignore')
541551

@@ -1248,16 +1258,18 @@ def shift(self, periods, axis=0, mgr=None):
12481258

12491259
return [self.make_block(new_values, fastpath=True)]
12501260

1251-
def eval(self, func, other, raise_on_error=True, try_cast=False, mgr=None):
1261+
def eval(self, func, other, errors='raise', try_cast=False, mgr=None):
12521262
"""
12531263
evaluate the block; return result block from the result
12541264
12551265
Parameters
12561266
----------
12571267
func : how to combine self, other
12581268
other : a ndarray/object
1259-
raise_on_error : if True, raise when I can't perform the function,
1260-
False by default (and just return the data that we had coming in)
1269+
errors : str, {'raise', 'ignore'}, default 'raise'
1270+
- ``raise`` : allow exceptions to be raised
1271+
- ``ignore`` : suppress exceptions. On error return original object
1272+
12611273
try_cast : try casting the results to the input type
12621274
12631275
Returns
@@ -1295,7 +1307,7 @@ def eval(self, func, other, raise_on_error=True, try_cast=False, mgr=None):
12951307
except TypeError:
12961308
block = self.coerce_to_target_dtype(orig_other)
12971309
return block.eval(func, orig_other,
1298-
raise_on_error=raise_on_error,
1310+
errors=errors,
12991311
try_cast=try_cast, mgr=mgr)
13001312

13011313
# get the result, may need to transpose the other
@@ -1337,7 +1349,7 @@ def get_result(other):
13371349
# error handler if we have an issue operating with the function
13381350
def handle_error():
13391351

1340-
if raise_on_error:
1352+
if errors == 'raise':
13411353
# The 'detail' variable is defined in outer scope.
13421354
raise TypeError('Could not operate %s with block values %s' %
13431355
(repr(other), str(detail))) # noqa
@@ -1383,7 +1395,7 @@ def handle_error():
13831395
result = _block_shape(result, ndim=self.ndim)
13841396
return [self.make_block(result, fastpath=True, )]
13851397

1386-
def where(self, other, cond, align=True, raise_on_error=True,
1398+
def where(self, other, cond, align=True, errors='raise',
13871399
try_cast=False, axis=0, transpose=False, mgr=None):
13881400
"""
13891401
evaluate the block; return result block(s) from the result
@@ -1393,8 +1405,10 @@ def where(self, other, cond, align=True, raise_on_error=True,
13931405
other : a ndarray/object
13941406
cond : the condition to respect
13951407
align : boolean, perform alignment on other/cond
1396-
raise_on_error : if True, raise when I can't perform the function,
1397-
False by default (and just return the data that we had coming in)
1408+
errors : str, {'raise', 'ignore'}, default 'raise'
1409+
- ``raise`` : allow exceptions to be raised
1410+
- ``ignore`` : suppress exceptions. On error return original object
1411+
13981412
axis : int
13991413
transpose : boolean
14001414
Set to True if self is stored with axes reversed
@@ -1404,6 +1418,7 @@ def where(self, other, cond, align=True, raise_on_error=True,
14041418
a new block(s), the result of the func
14051419
"""
14061420
import pandas.core.computation.expressions as expressions
1421+
assert errors in ['raise', 'ignore']
14071422

14081423
values = self.values
14091424
orig_other = other
@@ -1436,9 +1451,9 @@ def func(cond, values, other):
14361451

14371452
try:
14381453
return self._try_coerce_result(expressions.where(
1439-
cond, values, other, raise_on_error=True))
1454+
cond, values, other))
14401455
except Exception as detail:
1441-
if raise_on_error:
1456+
if errors == 'raise':
14421457
raise TypeError('Could not operate [%s] with block values '
14431458
'[%s]' % (repr(other), str(detail)))
14441459
else:
@@ -1454,10 +1469,10 @@ def func(cond, values, other):
14541469
except TypeError:
14551470

14561471
# we cannot coerce, return a compat dtype
1457-
# we are explicity ignoring raise_on_error here
1472+
# we are explicity ignoring errors
14581473
block = self.coerce_to_target_dtype(other)
14591474
blocks = block.where(orig_other, cond, align=align,
1460-
raise_on_error=raise_on_error,
1475+
errors=errors,
14611476
try_cast=try_cast, axis=axis,
14621477
transpose=transpose)
14631478
return self._maybe_downcast(blocks, 'infer')
@@ -2745,7 +2760,7 @@ def sp_index(self):
27452760
def kind(self):
27462761
return self.values.kind
27472762

2748-
def _astype(self, dtype, copy=False, raise_on_error=True, values=None,
2763+
def _astype(self, dtype, copy=False, errors='raise', values=None,
27492764
klass=None, mgr=None, **kwargs):
27502765
if values is None:
27512766
values = self.values

0 commit comments

Comments
 (0)