Skip to content

Commit 1581a05

Browse files
committed
DEPR: deprecate .select() in favor of .loc(axis=)[]
closes pandas-dev#12401
1 parent d1fe892 commit 1581a05

File tree

9 files changed

+203
-60
lines changed

9 files changed

+203
-60
lines changed

doc/source/whatsnew/v0.21.0.txt

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

295+
.. _whatsnew_0210.api_breaking.select:
296+
297+
Select method is deprecated
298+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
299+
300+
The :meth:`Series.select` and :meth:`DataFrame.select` methods are deprecated in favor of using ``.loc[]`` (:issue:`12401`)
301+
302+
.. ipython:: python
303+
304+
df = DataFrame({'A': [1, 2, 3]}, index=['foo', 'bar', 'baz'])
305+
306+
.. code_block:: ipython
307+
308+
In [3]: df.select(lambda x: x in ['bar', 'baz'])
309+
FutureWarning: select is deprecated and will be removed in a future release. You can use .loc(axis=)[crit] as a replacement
310+
Out[3]:
311+
A
312+
bar 2
313+
baz 3
314+
315+
.. ipython:: python
316+
317+
df.loc[lambda x: x in ['bar', 'baz']]
318+
295319
.. _whatsnew_0210.api.na_changes:
296320

297321
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
"""
449456
if callable(maybe_callable):
450-
return maybe_callable(obj, **kwargs)
457+
458+
def try_for_axis(axis):
459+
labels = obj._get_axis(axis)
460+
return labels.map(maybe_callable, **kwargs).values
461+
462+
# act on labels
463+
if axis is not None:
464+
try:
465+
return try_for_axis(axis)
466+
except AttributeError:
467+
pass
468+
469+
# act on object
470+
try:
471+
return maybe_callable(obj, **kwargs)
472+
except (AttributeError, ValueError, TypeError):
473+
pass
474+
475+
# act on the axis=0
476+
try:
477+
return try_for_axis(0)
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
@@ -2279,6 +2279,8 @@ def select(self, crit, axis=0):
22792279
"""
22802280
Return data corresponding to axis labels matching criteria
22812281
2282+
DEPRECATED: use .loc(axis=)[crit] to select via labels
2283+
22822284
Parameters
22832285
----------
22842286
crit : function
@@ -2289,6 +2291,11 @@ def select(self, crit, axis=0):
22892291
-------
22902292
selection : type of caller
22912293
"""
2294+
warnings.warn("select is deprecated and will be removed in a "
2295+
"future release. You can use "
2296+
".loc(axis=)[crit] as a replacement",
2297+
FutureWarning, stacklevel=2)
2298+
22922299
axis = self._get_axis_number(axis)
22932300
axis_name = self._get_axis_name(axis)
22942301
axis_values = self._get_axis(axis)
@@ -2991,7 +2998,7 @@ def filter(self, items=None, like=None, regex=None, axis=None):
29912998
29922999
See Also
29933000
--------
2994-
pandas.DataFrame.select
3001+
pandas.DataFrame.loc
29953002
29963003
Notes
29973004
-----
@@ -3010,20 +3017,23 @@ def filter(self, items=None, like=None, regex=None, axis=None):
30103017

30113018
if axis is None:
30123019
axis = self._info_axis_name
3013-
axis_name = self._get_axis_name(axis)
3014-
axis_values = self._get_axis(axis_name)
3020+
labels = self._get_axis(axis)
30153021

30163022
if items is not None:
3017-
return self.reindex(**{axis_name:
3018-
[r for r in items if r in axis_values]})
3023+
name = self._get_axis_name(axis)
3024+
return self.reindex(
3025+
**{name: [r for r in items if r in labels]})
30193026
elif like:
3020-
matchf = lambda x: (like in x if isinstance(x, string_types) else
3021-
like in str(x))
3022-
return self.select(matchf, axis=axis_name)
3027+
def f(x):
3028+
if not isinstance(x, string_types):
3029+
x = str(x)
3030+
return like in x
3031+
values = labels.map(f)
3032+
return self.loc(axis=axis)[values.values]
30233033
elif regex:
30243034
matcher = re.compile(regex)
3025-
return self.select(lambda x: matcher.search(str(x)) is not None,
3026-
axis=axis_name)
3035+
values = labels.map(lambda x: matcher.search(str(x)) is not None)
3036+
return self.loc(axis=axis)[values.values]
30273037
else:
30283038
raise TypeError('Must pass either `items`, `like`, or `regex`')
30293039

@@ -5643,7 +5653,7 @@ def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
56435653
inplace = validate_bool_kwarg(inplace, 'inplace')
56445654

56455655
# align the cond to same shape as myself
5646-
cond = com._apply_if_callable(cond, self)
5656+
cond = com._apply_if_callable(cond, self, axis=axis)
56475657
if isinstance(cond, NDFrame):
56485658
cond, _ = cond.align(self, join='right', broadcast_axis=1)
56495659
else:
@@ -5865,7 +5875,7 @@ def _where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
58655875
def where(self, cond, other=np.nan, inplace=False, axis=None, level=None,
58665876
try_cast=False, raise_on_error=True):
58675877

5868-
other = com._apply_if_callable(other, self)
5878+
other = com._apply_if_callable(other, self, axis=axis)
58695879
return self._where(cond, other, inplace, axis, level, try_cast,
58705880
raise_on_error)
58715881

@@ -5875,7 +5885,7 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None,
58755885
try_cast=False, raise_on_error=True):
58765886

58775887
inplace = validate_bool_kwarg(inplace, 'inplace')
5878-
cond = com._apply_if_callable(cond, self)
5888+
cond = com._apply_if_callable(cond, self, axis=axis)
58795889

58805890
return self.where(~cond, other=other, inplace=inplace, axis=axis,
58815891
level=level, try_cast=try_cast,

0 commit comments

Comments
 (0)