Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEPR: deprecate raise_on_error in .where/.mask in favor of errors= #17744

Merged
merged 1 commit into from
Oct 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion doc/source/whatsnew/v0.21.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -666,8 +666,9 @@ Deprecations
- ``pd.TimeGrouper`` is deprecated in favor of :class:`pandas.Grouper` (:issue:`16747`)
- ``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`)
- 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`)
- Passing a non-existent column in ``.to_excel(..., columns=)`` is deprecated and will raise a ``KeyError`` in the future (:issue:`17295`)
- ``.get_value`` and ``.set_value`` on ``Series``, ``DataFrame``, ``Panel``, ``SparseSeries``, and ``SparseDataFrame`` are deprecated in favor of using ``.iat[]`` or ``.at[]`` accessors (:issue:`15269`)
- Passing a non-existant column in ``.to_excel(..., columns=)`` is deprecated and will raise a ``KeyError`` in the future (:issue:`17295`)
- ``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`)

.. _whatsnew_0210.deprecations.select:

Expand Down
38 changes: 14 additions & 24 deletions pandas/core/computation/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def set_numexpr_threads(n=None):
ne.set_num_threads(n)


def _evaluate_standard(op, op_str, a, b, raise_on_error=True, **eval_kwargs):
def _evaluate_standard(op, op_str, a, b, **eval_kwargs):
""" standard evaluation """
if _TEST_MODE:
_store_test_result(False)
Expand Down Expand Up @@ -89,7 +89,7 @@ def _can_use_numexpr(op, op_str, a, b, dtype_check):
return False


def _evaluate_numexpr(op, op_str, a, b, raise_on_error=False, truediv=True,
def _evaluate_numexpr(op, op_str, a, b, truediv=True,
reversed=False, **eval_kwargs):
result = None

Expand All @@ -111,25 +111,22 @@ def _evaluate_numexpr(op, op_str, a, b, raise_on_error=False, truediv=True,
except ValueError as detail:
if 'unknown type object' in str(detail):
pass
except Exception as detail:
if raise_on_error:
raise

if _TEST_MODE:
_store_test_result(result is not None)

if result is None:
result = _evaluate_standard(op, op_str, a, b, raise_on_error)
result = _evaluate_standard(op, op_str, a, b)

return result


def _where_standard(cond, a, b, raise_on_error=True):
def _where_standard(cond, a, b):
return np.where(_values_from_object(cond), _values_from_object(a),
_values_from_object(b))


def _where_numexpr(cond, a, b, raise_on_error=False):
def _where_numexpr(cond, a, b):
result = None

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

if result is None:
result = _where_standard(cond, a, b, raise_on_error)
result = _where_standard(cond, a, b)

return result

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


def evaluate(op, op_str, a, b, raise_on_error=False, use_numexpr=True,
def evaluate(op, op_str, a, b, use_numexpr=True,
**eval_kwargs):
""" evaluate and return the expression of the op on a and b

Expand All @@ -200,19 +196,16 @@ def evaluate(op, op_str, a, b, raise_on_error=False, use_numexpr=True,
op_str: the string version of the op
a : left operand
b : right operand
raise_on_error : pass the error to the higher level if indicated
(default is False), otherwise evaluate the op with and
return the results
use_numexpr : whether to try to use numexpr (default True)
"""

use_numexpr = use_numexpr and _bool_arith_check(op_str, a, b)
if use_numexpr:
return _evaluate(op, op_str, a, b, raise_on_error=raise_on_error,
**eval_kwargs)
return _evaluate_standard(op, op_str, a, b, raise_on_error=raise_on_error)
return _evaluate(op, op_str, a, b, **eval_kwargs)
return _evaluate_standard(op, op_str, a, b)


def where(cond, a, b, raise_on_error=False, use_numexpr=True):
def where(cond, a, b, use_numexpr=True):
""" evaluate the where condition cond on a and b

Parameters
Expand All @@ -221,15 +214,12 @@ def where(cond, a, b, raise_on_error=False, use_numexpr=True):
cond : a boolean array
a : return if cond is True
b : return if cond is False
raise_on_error : pass the error to the higher level if indicated
(default is False), otherwise evaluate the op with and
return the results
use_numexpr : whether to try to use numexpr (default True)
"""

if use_numexpr:
return _where(cond, a, b, raise_on_error=raise_on_error)
return _where_standard(cond, a, b, raise_on_error=raise_on_error)
return _where(cond, a, b)
return _where_standard(cond, a, b)


def set_test_mode(v=True):
Expand Down
10 changes: 4 additions & 6 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -3862,9 +3862,9 @@ def _combine_match_columns(self, other, func, level=None,
try_cast=try_cast)
return self._constructor(new_data)

def _combine_const(self, other, func, raise_on_error=True, try_cast=True):
def _combine_const(self, other, func, errors='raise', try_cast=True):
new_data = self._data.eval(func=func, other=other,
raise_on_error=raise_on_error,
errors=errors,
try_cast=try_cast)
return self._constructor(new_data)

Expand Down Expand Up @@ -4035,8 +4035,7 @@ def combiner(x, y, needs_i8_conversion=False):
else:
mask = isna(x_values)

return expressions.where(mask, y_values, x_values,
raise_on_error=True)
return expressions.where(mask, y_values, x_values)

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

Expand Down Expand Up @@ -4091,8 +4090,7 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
if mask.all():
continue

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

# ----------------------------------------------------------------------
# Misc methods
Expand Down
45 changes: 38 additions & 7 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5758,7 +5758,7 @@ def _align_series(self, other, join='outer', axis=None, level=None,
return left.__finalize__(self), right.__finalize__(other)

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

else:
new_data = self._data.where(other=other, cond=cond, align=align,
raise_on_error=raise_on_error,
errors=errors,
try_cast=try_cast, axis=block_axis,
transpose=self._AXIS_REVERSED)

Expand Down Expand Up @@ -5924,12 +5924,21 @@ def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
Whether to perform the operation in place on the data
axis : alignment axis if needed, default None
level : alignment level if needed, default None
errors : str, {'raise', 'ignore'}, default 'raise'
- ``raise`` : allow exceptions to be raised
- ``ignore`` : suppress exceptions. On error return original object

Note that currently this parameter won't affect
the results and will always coerce to a suitable dtype.

try_cast : boolean, default False
try to cast the result back to the input type (if possible),
raise_on_error : boolean, default True
Whether to raise on invalid data types (e.g. trying to where on
strings)

.. deprecated:: 0.21.0

Returns
-------
wh : same type as caller
Expand Down Expand Up @@ -6005,24 +6014,46 @@ def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
cond_rev="False", name='where',
name_other='mask'))
def where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
try_cast=False, raise_on_error=True):
errors='raise', try_cast=False, raise_on_error=None):

if raise_on_error is not None:
warnings.warn(
"raise_on_error is deprecated in "
"favor of errors='raise|ignore'",
FutureWarning, stacklevel=2)

if raise_on_error:
errors = 'raise'
else:
errors = 'ignore'

other = com._apply_if_callable(other, self)
return self._where(cond, other, inplace, axis, level, try_cast,
raise_on_error)
return self._where(cond, other, inplace, axis, level,
errors=errors, try_cast=try_cast)

@Appender(_shared_docs['where'] % dict(_shared_doc_kwargs, cond="False",
cond_rev="True", name='mask',
name_other='where'))
def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None,
try_cast=False, raise_on_error=True):
errors='raise', try_cast=False, raise_on_error=None):

if raise_on_error is not None:
warnings.warn(
"raise_on_error is deprecated in "
"favor of errors='raise|ignore'",
FutureWarning, stacklevel=2)

if raise_on_error:
errors = 'raise'
else:
errors = 'ignore'

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

return self.where(~cond, other=other, inplace=inplace, axis=axis,
level=level, try_cast=try_cast,
raise_on_error=raise_on_error)
errors=errors)

_shared_docs['shift'] = ("""
Shift index by desired number of periods with an optional time freq
Expand Down
43 changes: 27 additions & 16 deletions pandas/core/internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,10 +533,16 @@ def astype(self, dtype, copy=False, errors='raise', values=None, **kwargs):
**kwargs)

def _astype(self, dtype, copy=False, errors='raise', values=None,
klass=None, mgr=None, raise_on_error=False, **kwargs):
klass=None, mgr=None, **kwargs):
"""
Coerce to the new type (if copy=True, return a new copy)
raise on an except if raise == True
Coerce to the new type

dtype : str, dtype convertible
copy : boolean, default False
copy if indicated
errors : str, {'raise', 'ignore'}, default 'ignore'
- ``raise`` : allow exceptions to be raised
- ``ignore`` : suppress exceptions. On error return original object
"""
errors_legal_values = ('raise', 'ignore')

Expand Down Expand Up @@ -1248,16 +1254,18 @@ def shift(self, periods, axis=0, mgr=None):

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

def eval(self, func, other, raise_on_error=True, try_cast=False, mgr=None):
def eval(self, func, other, errors='raise', try_cast=False, mgr=None):
"""
evaluate the block; return result block from the result

Parameters
----------
func : how to combine self, other
other : a ndarray/object
raise_on_error : if True, raise when I can't perform the function,
False by default (and just return the data that we had coming in)
errors : str, {'raise', 'ignore'}, default 'raise'
- ``raise`` : allow exceptions to be raised
- ``ignore`` : suppress exceptions. On error return original object

try_cast : try casting the results to the input type

Returns
Expand Down Expand Up @@ -1295,7 +1303,7 @@ def eval(self, func, other, raise_on_error=True, try_cast=False, mgr=None):
except TypeError:
block = self.coerce_to_target_dtype(orig_other)
return block.eval(func, orig_other,
raise_on_error=raise_on_error,
errors=errors,
try_cast=try_cast, mgr=mgr)

# get the result, may need to transpose the other
Expand Down Expand Up @@ -1337,7 +1345,7 @@ def get_result(other):
# error handler if we have an issue operating with the function
def handle_error():

if raise_on_error:
if errors == 'raise':
# The 'detail' variable is defined in outer scope.
raise TypeError('Could not operate %s with block values %s' %
(repr(other), str(detail))) # noqa
Expand Down Expand Up @@ -1383,7 +1391,7 @@ def handle_error():
result = _block_shape(result, ndim=self.ndim)
return [self.make_block(result, fastpath=True, )]

def where(self, other, cond, align=True, raise_on_error=True,
def where(self, other, cond, align=True, errors='raise',
try_cast=False, axis=0, transpose=False, mgr=None):
"""
evaluate the block; return result block(s) from the result
Expand All @@ -1393,8 +1401,10 @@ def where(self, other, cond, align=True, raise_on_error=True,
other : a ndarray/object
cond : the condition to respect
align : boolean, perform alignment on other/cond
raise_on_error : if True, raise when I can't perform the function,
False by default (and just return the data that we had coming in)
errors : str, {'raise', 'ignore'}, default 'raise'
- ``raise`` : allow exceptions to be raised
- ``ignore`` : suppress exceptions. On error return original object

axis : int
transpose : boolean
Set to True if self is stored with axes reversed
Expand All @@ -1404,6 +1414,7 @@ def where(self, other, cond, align=True, raise_on_error=True,
a new block(s), the result of the func
"""
import pandas.core.computation.expressions as expressions
assert errors in ['raise', 'ignore']

values = self.values
orig_other = other
Expand Down Expand Up @@ -1436,9 +1447,9 @@ def func(cond, values, other):

try:
return self._try_coerce_result(expressions.where(
cond, values, other, raise_on_error=True))
cond, values, other))
except Exception as detail:
if raise_on_error:
if errors == 'raise':
raise TypeError('Could not operate [%s] with block values '
'[%s]' % (repr(other), str(detail)))
else:
Expand All @@ -1454,10 +1465,10 @@ def func(cond, values, other):
except TypeError:

# we cannot coerce, return a compat dtype
# we are explicity ignoring raise_on_error here
# we are explicity ignoring errors
block = self.coerce_to_target_dtype(other)
blocks = block.where(orig_other, cond, align=align,
raise_on_error=raise_on_error,
errors=errors,
try_cast=try_cast, axis=axis,
transpose=transpose)
return self._maybe_downcast(blocks, 'infer')
Expand Down Expand Up @@ -2745,7 +2756,7 @@ def sp_index(self):
def kind(self):
return self.values.kind

def _astype(self, dtype, copy=False, raise_on_error=True, values=None,
def _astype(self, dtype, copy=False, errors='raise', values=None,
klass=None, mgr=None, **kwargs):
if values is None:
values = self.values
Expand Down
Loading