Skip to content

Commit 35812d0

Browse files
committed
DEPR: Deprecate convert parameter in take
xref gh-16948. The parameter is not respected, nor is it a parameter in many 'take' implementations.
1 parent 4004367 commit 35812d0

File tree

11 files changed

+141
-73
lines changed

11 files changed

+141
-73
lines changed

doc/source/whatsnew/v0.21.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ Other API Changes
441441
Deprecations
442442
~~~~~~~~~~~~
443443
- :func:`read_excel()` has deprecated ``sheetname`` in favor of ``sheet_name`` for consistency with ``.to_excel()`` (:issue:`10559`).
444-
444+
- The ``convert`` parameter has been deprecated in the ``.take()`` method, as it was not being respected (:issue:`16948`)
445445
- ``pd.options.html.border`` has been deprecated in favor of ``pd.options.display.html.border`` (:issue:`15793`).
446446

447447
- :func:`SeriesGroupBy.nth` has deprecated ``True`` in favor of ``'all'`` for its kwarg ``dropna`` (:issue:`11038`).

pandas/core/frame.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -2032,7 +2032,7 @@ def _ixs(self, i, axis=0):
20322032
return self.loc[:, lab_slice]
20332033
else:
20342034
if isinstance(label, Index):
2035-
return self.take(i, axis=1, convert=True)
2035+
return self.take(i, axis=1)
20362036

20372037
index_len = len(self.index)
20382038

@@ -2114,10 +2114,10 @@ def _getitem_array(self, key):
21142114
# be reindexed to match DataFrame rows
21152115
key = check_bool_indexer(self.index, key)
21162116
indexer = key.nonzero()[0]
2117-
return self.take(indexer, axis=0, convert=False)
2117+
return self.take(indexer, axis=0)
21182118
else:
21192119
indexer = self.loc._convert_to_indexer(key, axis=1)
2120-
return self.take(indexer, axis=1, convert=True)
2120+
return self.take(indexer, axis=1)
21212121

21222122
def _getitem_multilevel(self, key):
21232123
loc = self.columns.get_loc(key)
@@ -3349,7 +3349,7 @@ def dropna(self, axis=0, how='any', thresh=None, subset=None,
33493349
else:
33503350
raise TypeError('must specify how or thresh')
33513351

3352-
result = self.take(mask.nonzero()[0], axis=axis, convert=False)
3352+
result = self.take(mask.nonzero()[0], axis=axis)
33533353

33543354
if inplace:
33553355
self._update_inplace(result)
@@ -3485,7 +3485,7 @@ def trans(v):
34853485

34863486
new_data = self._data.take(indexer,
34873487
axis=self._get_block_manager_axis(axis),
3488-
convert=False, verify=False)
3488+
verify=False)
34893489

34903490
if inplace:
34913491
return self._update_inplace(new_data)
@@ -3546,7 +3546,7 @@ def sort_index(self, axis=0, level=None, ascending=True, inplace=False,
35463546
baxis = self._get_block_manager_axis(axis)
35473547
new_data = self._data.take(indexer,
35483548
axis=baxis,
3549-
convert=False, verify=False)
3549+
verify=False)
35503550

35513551
# reconstruct axis if needed
35523552
new_data.axes[baxis] = new_data.axes[baxis]._sort_levels_monotonic()

pandas/core/generic.py

+76-19
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from pandas.core.index import (Index, MultiIndex, _ensure_index,
3939
InvalidIndexError)
4040
import pandas.core.indexing as indexing
41+
from pandas.core.indexing import maybe_convert_indices
4142
from pandas.core.indexes.datetimes import DatetimeIndex
4243
from pandas.core.indexes.period import PeriodIndex, Period
4344
from pandas.core.internals import BlockManager
@@ -1820,7 +1821,7 @@ def _iget_item_cache(self, item):
18201821
if ax.is_unique:
18211822
lower = self._get_item_cache(ax[item])
18221823
else:
1823-
lower = self.take(item, axis=self._info_axis_number, convert=True)
1824+
lower = self.take(item, axis=self._info_axis_number)
18241825
return lower
18251826

18261827
def _box_item_values(self, key, values):
@@ -2055,8 +2056,63 @@ def __delitem__(self, key):
20552056
except KeyError:
20562057
pass
20572058

2058-
def take(self, indices, axis=0, convert=True, is_copy=True, **kwargs):
2059+
_shared_docs['_take'] = """
2060+
Return the elements in the given *positional* indices along an axis.
2061+
2062+
This means that we are not indexing according to actual values in
2063+
the index attribute of the object. We are indexing according to the
2064+
actual position of the element in the object.
2065+
2066+
This is the internal version of ``.take()`` and will contain a wider
2067+
selection of parameters useful for internal use but not as suitable
2068+
for public usage.
2069+
2070+
Parameters
2071+
----------
2072+
indices : array-like
2073+
An array of ints indicating which positions to take.
2074+
axis : int, default 0
2075+
The axis on which to select elements. "0" means that we are
2076+
selecting rows, "1" means that we are selecting columns, etc.
2077+
convert : bool, default True
2078+
Whether to convert negative indices into positive ones.
2079+
For example, ``-1`` would map to the ``len(axis) - 1``.
2080+
The conversions are similar to the behavior of indexing a
2081+
regular Python list.
2082+
is_copy : bool, default True
2083+
Whether to return a copy of the original object or not.
2084+
2085+
Returns
2086+
-------
2087+
taken : type of caller
2088+
An array-like containing the elements taken from the object.
2089+
2090+
See Also
2091+
--------
2092+
numpy.ndarray.take
2093+
numpy.take
20592094
"""
2095+
2096+
@Appender(_shared_docs['_take'])
2097+
def _take(self, indices, axis=0, convert=True, is_copy=False):
2098+
self._consolidate_inplace()
2099+
2100+
if convert:
2101+
indices = maybe_convert_indices(indices, len(self._get_axis(axis)))
2102+
2103+
new_data = self._data.take(indices,
2104+
axis=self._get_block_manager_axis(axis),
2105+
verify=True)
2106+
result = self._constructor(new_data).__finalize__(self)
2107+
2108+
# Maybe set copy if we didn't actually change the index.
2109+
if is_copy:
2110+
if not result._get_axis(axis).equals(self._get_axis(axis)):
2111+
result._set_is_copy(self)
2112+
2113+
return result
2114+
2115+
_shared_docs['take'] = """
20602116
Return the elements in the given *positional* indices along an axis.
20612117
20622118
This means that we are not indexing according to actual values in
@@ -2071,9 +2127,12 @@ def take(self, indices, axis=0, convert=True, is_copy=True, **kwargs):
20712127
The axis on which to select elements. "0" means that we are
20722128
selecting rows, "1" means that we are selecting columns, etc.
20732129
convert : bool, default True
2074-
Whether to convert negative indices to positive ones, just as with
2075-
indexing into Python lists. For example, if `-1` was passed in,
2076-
this index would be converted ``n - 1``.
2130+
.. deprecated:: 0.21.0
2131+
2132+
Whether to convert negative indices into positive ones.
2133+
For example, ``-1`` would map to the ``len(axis) - 1``.
2134+
The conversions are similar to the behavior of indexing a
2135+
regular Python list.
20772136
is_copy : bool, default True
20782137
Whether to return a copy of the original object or not.
20792138
@@ -2129,19 +2188,17 @@ class max_speed
21292188
numpy.ndarray.take
21302189
numpy.take
21312190
"""
2191+
2192+
@Appender(_shared_docs['take'])
2193+
def take(self, indices, axis=0, convert=True, is_copy=True, **kwargs):
21322194
nv.validate_take(tuple(), kwargs)
2133-
self._consolidate_inplace()
2134-
new_data = self._data.take(indices,
2135-
axis=self._get_block_manager_axis(axis),
2136-
convert=True, verify=True)
2137-
result = self._constructor(new_data).__finalize__(self)
21382195

2139-
# maybe set copy if we didn't actually change the index
2140-
if is_copy:
2141-
if not result._get_axis(axis).equals(self._get_axis(axis)):
2142-
result._set_is_copy(self)
2196+
if not convert:
2197+
msg = ("The 'convert' parameter is deprecated "
2198+
"and will be removed in a future version.")
2199+
warnings.warn(msg, FutureWarning, stacklevel=2)
21432200

2144-
return result
2201+
return self._take(indices, axis=axis, convert=convert, is_copy=is_copy)
21452202

21462203
def xs(self, key, axis=0, level=None, drop_level=True):
21472204
"""
@@ -2242,9 +2299,9 @@ def xs(self, key, axis=0, level=None, drop_level=True):
22422299
if isinstance(loc, np.ndarray):
22432300
if loc.dtype == np.bool_:
22442301
inds, = loc.nonzero()
2245-
return self.take(inds, axis=axis, convert=False)
2302+
return self.take(inds, axis=axis)
22462303
else:
2247-
return self.take(loc, axis=axis, convert=True)
2304+
return self.take(loc, axis=axis)
22482305

22492306
if not is_scalar(loc):
22502307
new_index = self.index[loc]
@@ -5057,7 +5114,7 @@ def at_time(self, time, asof=False):
50575114
"""
50585115
try:
50595116
indexer = self.index.indexer_at_time(time, asof=asof)
5060-
return self.take(indexer, convert=False)
5117+
return self.take(indexer)
50615118
except AttributeError:
50625119
raise TypeError('Index must be DatetimeIndex')
50635120

@@ -5081,7 +5138,7 @@ def between_time(self, start_time, end_time, include_start=True,
50815138
indexer = self.index.indexer_between_time(
50825139
start_time, end_time, include_start=include_start,
50835140
include_end=include_end)
5084-
return self.take(indexer, convert=False)
5141+
return self.take(indexer)
50855142
except AttributeError:
50865143
raise TypeError('Index must be DatetimeIndex')
50875144

pandas/core/groupby.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def _set_grouper(self, obj, sort=False):
320320
indexer = self.indexer = ax.argsort(kind='mergesort')
321321
ax = ax.take(indexer)
322322
obj = obj.take(indexer, axis=self.axis,
323-
convert=False, is_copy=False)
323+
is_copy=False)
324324

325325
self.obj = obj
326326
self.grouper = ax
@@ -643,7 +643,7 @@ def get_group(self, name, obj=None):
643643
if not len(inds):
644644
raise KeyError(name)
645645

646-
return obj.take(inds, axis=self.axis, convert=False)
646+
return obj.take(inds, axis=self.axis)
647647

648648
def __iter__(self):
649649
"""
@@ -2202,7 +2202,7 @@ def _aggregate_series_fast(self, obj, func):
22022202
# avoids object / Series creation overhead
22032203
dummy = obj._get_values(slice(None, 0)).to_dense()
22042204
indexer = get_group_index_sorter(group_index, ngroups)
2205-
obj = obj.take(indexer, convert=False).to_dense()
2205+
obj = obj.take(indexer).to_dense()
22062206
group_index = algorithms.take_nd(
22072207
group_index, indexer, allow_fill=False)
22082208
grouper = lib.SeriesGrouper(obj, func, group_index, ngroups,
@@ -4435,7 +4435,7 @@ def __iter__(self):
44354435
yield i, self._chop(sdata, slice(start, end))
44364436

44374437
def _get_sorted_data(self):
4438-
return self.data.take(self.sort_idx, axis=self.axis, convert=False)
4438+
return self.data._take(self.sort_idx, axis=self.axis, convert=False)
44394439

44404440
def _chop(self, sdata, slice_obj):
44414441
return sdata.iloc[slice_obj]

pandas/core/indexing.py

+8-9
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,7 @@ def _getitem_iterable(self, key, axis=0):
10931093
if is_bool_indexer(key):
10941094
key = check_bool_indexer(labels, key)
10951095
inds, = key.nonzero()
1096-
return self.obj.take(inds, axis=axis, convert=False)
1096+
return self.obj.take(inds, axis=axis)
10971097
else:
10981098
# Have the index compute an indexer or return None
10991099
# if it cannot handle; we only act on all found values
@@ -1126,15 +1126,14 @@ def _getitem_iterable(self, key, axis=0):
11261126
keyarr)
11271127

11281128
if new_indexer is not None:
1129-
result = self.obj.take(indexer[indexer != -1], axis=axis,
1130-
convert=False)
1129+
result = self.obj.take(indexer[indexer != -1], axis=axis)
11311130

11321131
result = result._reindex_with_indexers(
11331132
{axis: [new_target, new_indexer]},
11341133
copy=True, allow_dups=True)
11351134

11361135
else:
1137-
result = self.obj.take(indexer, axis=axis, convert=False)
1136+
result = self.obj.take(indexer, axis=axis)
11381137

11391138
return result
11401139

@@ -1265,7 +1264,7 @@ def _get_slice_axis(self, slice_obj, axis=0):
12651264
if isinstance(indexer, slice):
12661265
return self._slice(indexer, axis=axis, kind='iloc')
12671266
else:
1268-
return self.obj.take(indexer, axis=axis, convert=False)
1267+
return self.obj.take(indexer, axis=axis)
12691268

12701269

12711270
class _IXIndexer(_NDFrameIndexer):
@@ -1350,7 +1349,7 @@ def _getbool_axis(self, key, axis=0):
13501349
key = check_bool_indexer(labels, key)
13511350
inds, = key.nonzero()
13521351
try:
1353-
return self.obj.take(inds, axis=axis, convert=False)
1352+
return self.obj.take(inds, axis=axis)
13541353
except Exception as detail:
13551354
raise self._exception(detail)
13561355

@@ -1367,7 +1366,7 @@ def _get_slice_axis(self, slice_obj, axis=0):
13671366
if isinstance(indexer, slice):
13681367
return self._slice(indexer, axis=axis, kind='iloc')
13691368
else:
1370-
return self.obj.take(indexer, axis=axis, convert=False)
1369+
return self.obj.take(indexer, axis=axis)
13711370

13721371

13731372
class _LocIndexer(_LocationIndexer):
@@ -1707,7 +1706,7 @@ def _get_slice_axis(self, slice_obj, axis=0):
17071706
if isinstance(slice_obj, slice):
17081707
return self._slice(slice_obj, axis=axis, kind='iloc')
17091708
else:
1710-
return self.obj.take(slice_obj, axis=axis, convert=False)
1709+
return self.obj.take(slice_obj, axis=axis)
17111710

17121711
def _get_list_axis(self, key, axis=0):
17131712
"""
@@ -1723,7 +1722,7 @@ def _get_list_axis(self, key, axis=0):
17231722
Series object
17241723
"""
17251724
try:
1726-
return self.obj.take(key, axis=axis, convert=False)
1725+
return self.obj.take(key, axis=axis)
17271726
except IndexError:
17281727
# re-raise with different error message
17291728
raise IndexError("positional indexers are out-of-bounds")

pandas/core/series.py

+12-23
Original file line numberDiff line numberDiff line change
@@ -2545,35 +2545,24 @@ def memory_usage(self, index=True, deep=False):
25452545
v += self.index.memory_usage(deep=deep)
25462546
return v
25472547

2548-
def take(self, indices, axis=0, convert=True, is_copy=False, **kwargs):
2549-
"""
2550-
return Series corresponding to requested indices
2551-
2552-
Parameters
2553-
----------
2554-
indices : list / array of ints
2555-
convert : translate negative to positive indices (default)
2556-
2557-
Returns
2558-
-------
2559-
taken : Series
2560-
2561-
See also
2562-
--------
2563-
numpy.ndarray.take
2564-
"""
2565-
if kwargs:
2566-
nv.validate_take(tuple(), kwargs)
2567-
2568-
# check/convert indicies here
2548+
@Appender(generic._shared_docs['_take'])
2549+
def _take(self, indices, axis=0, convert=True, is_copy=False):
25692550
if convert:
25702551
indices = maybe_convert_indices(indices, len(self._get_axis(axis)))
25712552

25722553
indices = _ensure_platform_int(indices)
25732554
new_index = self.index.take(indices)
25742555
new_values = self._values.take(indices)
2575-
return (self._constructor(new_values, index=new_index, fastpath=True)
2576-
.__finalize__(self))
2556+
2557+
result = (self._constructor(new_values, index=new_index,
2558+
fastpath=True).__finalize__(self))
2559+
2560+
# Maybe set copy if we didn't actually change the index.
2561+
if is_copy:
2562+
if not result._get_axis(axis).equals(self._get_axis(axis)):
2563+
result._set_is_copy(self)
2564+
2565+
return result
25772566

25782567
def isin(self, values):
25792568
"""

pandas/core/sparse/series.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -602,16 +602,15 @@ def sparse_reindex(self, new_index):
602602
sparse_index=new_index,
603603
fill_value=self.fill_value).__finalize__(self)
604604

605+
@Appender(generic._shared_docs['take'])
605606
def take(self, indices, axis=0, convert=True, *args, **kwargs):
606-
"""
607-
Sparse-compatible version of ndarray.take
607+
convert = nv.validate_take_with_convert(convert, args, kwargs)
608608

609-
Returns
610-
-------
611-
taken : ndarray
612-
"""
609+
if not convert:
610+
msg = ("The 'convert' parameter is deprecated "
611+
"and will be removed in a future version.")
612+
warnings.warn(msg, FutureWarning, stacklevel=2)
613613

614-
convert = nv.validate_take_with_convert(convert, args, kwargs)
615614
new_values = SparseArray.take(self.values, indices)
616615
new_index = self.index.take(indices)
617616
return self._constructor(new_values,

0 commit comments

Comments
 (0)