Skip to content

Commit 9c6734a

Browse files
committed
DEPR: deprecate .select() in favor of .loc(axis=)[]
closes #12401
1 parent ad7d051 commit 9c6734a

File tree

9 files changed

+216
-61
lines changed

9 files changed

+216
-61
lines changed

doc/source/whatsnew/v0.21.0.txt

+24
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,30 @@ These now coerce to ``object`` dtype.
339339
- Inconsistent behavior in ``.where()`` with datetimelikes which would raise rather than coerce to ``object`` (:issue:`16402`)
340340
- Bug in assignment against ``int64`` data with ``np.ndarray`` with ``float64`` dtype may keep ``int64`` dtype (:issue:`14001`)
341341

342+
.. _whatsnew_0210.api_breaking.select:
343+
344+
Select method is deprecated
345+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
346+
347+
The :meth:`Series.select` and :meth:`DataFrame.select` methods are deprecated in favor of using ``.loc[]`` (:issue:`12401`)
348+
349+
.. ipython:: python
350+
351+
df = DataFrame({'A': [1, 2, 3]}, index=['foo', 'bar', 'baz'])
352+
353+
.. code_block:: ipython
354+
355+
In [3]: df.select(lambda x: x in ['bar', 'baz'])
356+
FutureWarning: select is deprecated and will be removed in a future release. You can use .loc[crit] as a replacement
357+
Out[3]:
358+
A
359+
bar 2
360+
baz 3
361+
362+
.. ipython:: python
363+
364+
df.loc[lambda x: x in ['bar', 'baz']]
365+
342366
.. _whatsnew_0210.api.na_changes:
343367

344368
NA naming Changes

pandas/core/common.py

+32-2
Original file line numberDiff line numberDiff line change
@@ -441,13 +441,43 @@ def _get_callable_name(obj):
441441
return None
442442

443443

444-
def _apply_if_callable(maybe_callable, obj, **kwargs):
444+
def _apply_if_callable(maybe_callable, obj, axis=None, **kwargs):
445445
"""
446446
Evaluate possibly callable input using obj and kwargs if it is callable,
447447
otherwise return as it is
448+
449+
Parameters
450+
----------
451+
maybe_callable : possibly a callable
452+
obj : NDFrame
453+
axis : int, optional
454+
**kwargs
448455
"""
456+
449457
if callable(maybe_callable):
450-
return maybe_callable(obj, **kwargs)
458+
459+
# act on object
460+
try:
461+
result = maybe_callable(obj, **kwargs)
462+
result = getattr(result, 'values', result)
463+
464+
# if we have asked for a specific axis
465+
# then we cannot be more than 1d
466+
if axis is not None:
467+
if getattr(result, 'ndim', 0) > 1:
468+
raise ValueError
469+
470+
return result
471+
except (AttributeError, ValueError, KeyError):
472+
pass
473+
474+
# act on the axis
475+
try:
476+
labels = obj._get_axis(axis or 0)
477+
return labels.map(maybe_callable, **kwargs).values
478+
except AttributeError:
479+
pass
480+
451481
return maybe_callable
452482

453483

pandas/core/generic.py

+23-13
Original file line numberDiff line numberDiff line change
@@ -2281,6 +2281,8 @@ def select(self, crit, axis=0):
22812281
"""
22822282
Return data corresponding to axis labels matching criteria
22832283
2284+
DEPRECATED: use .loc(axis=)[crit] to select via labels
2285+
22842286
Parameters
22852287
----------
22862288
crit : function
@@ -2291,6 +2293,11 @@ def select(self, crit, axis=0):
22912293
-------
22922294
selection : type of caller
22932295
"""
2296+
warnings.warn("select is deprecated and will be removed in a "
2297+
"future release. You can use "
2298+
".loc[crit] as a replacement",
2299+
FutureWarning, stacklevel=2)
2300+
22942301
axis = self._get_axis_number(axis)
22952302
axis_name = self._get_axis_name(axis)
22962303
axis_values = self._get_axis(axis)
@@ -3043,7 +3050,7 @@ def filter(self, items=None, like=None, regex=None, axis=None):
30433050
30443051
See Also
30453052
--------
3046-
pandas.DataFrame.select
3053+
pandas.DataFrame.loc
30473054
30483055
Notes
30493056
-----
@@ -3062,20 +3069,23 @@ def filter(self, items=None, like=None, regex=None, axis=None):
30623069

30633070
if axis is None:
30643071
axis = self._info_axis_name
3065-
axis_name = self._get_axis_name(axis)
3066-
axis_values = self._get_axis(axis_name)
3072+
labels = self._get_axis(axis)
30673073

30683074
if items is not None:
3069-
return self.reindex(**{axis_name:
3070-
[r for r in items if r in axis_values]})
3075+
name = self._get_axis_name(axis)
3076+
return self.reindex(
3077+
**{name: [r for r in items if r in labels]})
30713078
elif like:
3072-
matchf = lambda x: (like in x if isinstance(x, string_types) else
3073-
like in str(x))
3074-
return self.select(matchf, axis=axis_name)
3079+
def f(x):
3080+
if not isinstance(x, string_types):
3081+
x = str(x)
3082+
return like in x
3083+
values = labels.map(f)
3084+
return self.loc(axis=axis)[values.values]
30753085
elif regex:
30763086
matcher = re.compile(regex)
3077-
return self.select(lambda x: matcher.search(str(x)) is not None,
3078-
axis=axis_name)
3087+
values = labels.map(lambda x: matcher.search(str(x)) is not None)
3088+
return self.loc(axis=axis)[values.values]
30793089
else:
30803090
raise TypeError('Must pass either `items`, `like`, or `regex`')
30813091

@@ -5698,7 +5708,7 @@ def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
56985708
inplace = validate_bool_kwarg(inplace, 'inplace')
56995709

57005710
# align the cond to same shape as myself
5701-
cond = com._apply_if_callable(cond, self)
5711+
cond = com._apply_if_callable(cond, self, axis=axis)
57025712
if isinstance(cond, NDFrame):
57035713
cond, _ = cond.align(self, join='right', broadcast_axis=1)
57045714
else:
@@ -5939,7 +5949,7 @@ def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
59395949
def where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
59405950
try_cast=False, raise_on_error=True):
59415951

5942-
other = com._apply_if_callable(other, self)
5952+
other = com._apply_if_callable(other, self, axis=axis)
59435953
return self._where(cond, other, inplace, axis, level, try_cast,
59445954
raise_on_error)
59455955

@@ -5950,7 +5960,7 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None,
59505960
try_cast=False, raise_on_error=True):
59515961

59525962
inplace = validate_bool_kwarg(inplace, 'inplace')
5953-
cond = com._apply_if_callable(cond, self)
5963+
cond = com._apply_if_callable(cond, self, axis=axis)
59545964

59555965
return self.where(~cond, other=other, inplace=inplace, axis=axis,
59565966
level=level, try_cast=try_cast,

0 commit comments

Comments
 (0)