Skip to content

Commit 9325f21

Browse files
committed
DEPR: Deprecate convert parameter in take
xref pandas-devgh-16948. The parameter is not respected, nor is it a parameter in many 'take' implementations.
1 parent 030e374 commit 9325f21

File tree

11 files changed

+144
-73
lines changed

11 files changed

+144
-73
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ Deprecations
490490
~~~~~~~~~~~~
491491

492492
- :func:`read_excel()` has deprecated ``sheetname`` in favor of ``sheet_name`` for consistency with ``.to_excel()`` (:issue:`10559`).
493+
- The ``convert`` parameter has been deprecated in the ``.take()`` method, as it was not being respected (:issue:`16948`)
493494
- ``pd.options.html.border`` has been deprecated in favor of ``pd.options.display.html.border`` (:issue:`15793`).
494495
- :func:`SeriesGroupBy.nth` has deprecated ``True`` in favor of ``'all'`` for its kwarg ``dropna`` (:issue:`11038`).
495496
- :func:`DataFrame.as_blocks` is deprecated, as this is exposing the internal implementation (:issue:`17302`)

Diff for: pandas/core/frame.py

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

20392039
index_len = len(self.index)
20402040

@@ -2116,10 +2116,10 @@ def _getitem_array(self, key):
21162116
# be reindexed to match DataFrame rows
21172117
key = check_bool_indexer(self.index, key)
21182118
indexer = key.nonzero()[0]
2119-
return self.take(indexer, axis=0, convert=False)
2119+
return self._take(indexer, axis=0, convert=False)
21202120
else:
21212121
indexer = self.loc._convert_to_indexer(key, axis=1)
2122-
return self.take(indexer, axis=1, convert=True)
2122+
return self._take(indexer, axis=1, convert=True)
21232123

21242124
def _getitem_multilevel(self, key):
21252125
loc = self.columns.get_loc(key)
@@ -3355,7 +3355,7 @@ def dropna(self, axis=0, how='any', thresh=None, subset=None,
33553355
else:
33563356
raise TypeError('must specify how or thresh')
33573357

3358-
result = self.take(mask.nonzero()[0], axis=axis, convert=False)
3358+
result = self._take(mask.nonzero()[0], axis=axis, convert=False)
33593359

33603360
if inplace:
33613361
self._update_inplace(result)
@@ -3486,7 +3486,7 @@ def sort_values(self, by, axis=0, ascending=True, inplace=False,
34863486

34873487
new_data = self._data.take(indexer,
34883488
axis=self._get_block_manager_axis(axis),
3489-
convert=False, verify=False)
3489+
verify=False)
34903490

34913491
if inplace:
34923492
return self._update_inplace(new_data)
@@ -3547,7 +3547,7 @@ def sort_index(self, axis=0, level=None, ascending=True, inplace=False,
35473547
baxis = self._get_block_manager_axis(axis)
35483548
new_data = self._data.take(indexer,
35493549
axis=baxis,
3550-
convert=False, verify=False)
3550+
verify=False)
35513551

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

Diff for: pandas/core/generic.py

+77-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
@@ -1822,7 +1823,8 @@ def _iget_item_cache(self, item):
18221823
if ax.is_unique:
18231824
lower = self._get_item_cache(ax[item])
18241825
else:
1825-
lower = self.take(item, axis=self._info_axis_number, convert=True)
1826+
lower = self._take(item, axis=self._info_axis_number,
1827+
convert=True)
18261828
return lower
18271829

18281830
def _box_item_values(self, key, values):
@@ -2057,8 +2059,63 @@ def __delitem__(self, key):
20572059
except KeyError:
20582060
pass
20592061

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

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

2146-
return result
2204+
return self._take(indices, axis=axis, convert=convert, is_copy=is_copy)
21472205

21482206
def xs(self, key, axis=0, level=None, drop_level=True):
21492207
"""
@@ -2244,9 +2302,9 @@ def xs(self, key, axis=0, level=None, drop_level=True):
22442302
if isinstance(loc, np.ndarray):
22452303
if loc.dtype == np.bool_:
22462304
inds, = loc.nonzero()
2247-
return self.take(inds, axis=axis, convert=False)
2305+
return self._take(inds, axis=axis, convert=False)
22482306
else:
2249-
return self.take(loc, axis=axis, convert=True)
2307+
return self._take(loc, axis=axis, convert=True)
22502308

22512309
if not is_scalar(loc):
22522310
new_index = self.index[loc]
@@ -5112,7 +5170,7 @@ def at_time(self, time, asof=False):
51125170
"""
51135171
try:
51145172
indexer = self.index.indexer_at_time(time, asof=asof)
5115-
return self.take(indexer, convert=False)
5173+
return self._take(indexer, convert=False)
51165174
except AttributeError:
51175175
raise TypeError('Index must be DatetimeIndex')
51185176

@@ -5136,7 +5194,7 @@ def between_time(self, start_time, end_time, include_start=True,
51365194
indexer = self.index.indexer_between_time(
51375195
start_time, end_time, include_start=include_start,
51385196
include_end=include_end)
5139-
return self.take(indexer, convert=False)
5197+
return self._take(indexer, convert=False)
51405198
except AttributeError:
51415199
raise TypeError('Index must be DatetimeIndex')
51425200

Diff for: pandas/core/groupby.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ def _set_grouper(self, obj, sort=False):
319319
# use stable sort to support first, last, nth
320320
indexer = self.indexer = ax.argsort(kind='mergesort')
321321
ax = ax.take(indexer)
322-
obj = obj.take(indexer, axis=self.axis,
323-
convert=False, is_copy=False)
322+
obj = obj._take(indexer, axis=self.axis,
323+
convert=False, 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, convert=False)
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, convert=False).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]

Diff for: pandas/core/indexing.py

+9-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, convert=False)
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,15 @@ 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,
1130+
convert=False)
11311131

11321132
result = result._reindex_with_indexers(
11331133
{axis: [new_target, new_indexer]},
11341134
copy=True, allow_dups=True)
11351135

11361136
else:
1137-
result = self.obj.take(indexer, axis=axis, convert=False)
1137+
result = self.obj._take(indexer, axis=axis)
11381138

11391139
return result
11401140

@@ -1265,7 +1265,7 @@ def _get_slice_axis(self, slice_obj, axis=0):
12651265
if isinstance(indexer, slice):
12661266
return self._slice(indexer, axis=axis, kind='iloc')
12671267
else:
1268-
return self.obj.take(indexer, axis=axis, convert=False)
1268+
return self.obj._take(indexer, axis=axis, convert=False)
12691269

12701270

12711271
class _IXIndexer(_NDFrameIndexer):
@@ -1350,7 +1350,7 @@ def _getbool_axis(self, key, axis=0):
13501350
key = check_bool_indexer(labels, key)
13511351
inds, = key.nonzero()
13521352
try:
1353-
return self.obj.take(inds, axis=axis, convert=False)
1353+
return self.obj._take(inds, axis=axis, convert=False)
13541354
except Exception as detail:
13551355
raise self._exception(detail)
13561356

@@ -1367,7 +1367,7 @@ def _get_slice_axis(self, slice_obj, axis=0):
13671367
if isinstance(indexer, slice):
13681368
return self._slice(indexer, axis=axis, kind='iloc')
13691369
else:
1370-
return self.obj.take(indexer, axis=axis, convert=False)
1370+
return self.obj._take(indexer, axis=axis, convert=False)
13711371

13721372

13731373
class _LocIndexer(_LocationIndexer):
@@ -1707,7 +1707,7 @@ def _get_slice_axis(self, slice_obj, axis=0):
17071707
if isinstance(slice_obj, slice):
17081708
return self._slice(slice_obj, axis=axis, kind='iloc')
17091709
else:
1710-
return self.obj.take(slice_obj, axis=axis, convert=False)
1710+
return self.obj._take(slice_obj, axis=axis, convert=False)
17111711

17121712
def _get_list_axis(self, key, axis=0):
17131713
"""
@@ -1723,7 +1723,7 @@ def _get_list_axis(self, key, axis=0):
17231723
Series object
17241724
"""
17251725
try:
1726-
return self.obj.take(key, axis=axis, convert=False)
1726+
return self.obj._take(key, axis=axis, convert=False)
17271727
except IndexError:
17281728
# re-raise with different error message
17291729
raise IndexError("positional indexers are out-of-bounds")

Diff for: pandas/core/series.py

+12-23
Original file line numberDiff line numberDiff line change
@@ -2563,35 +2563,24 @@ def memory_usage(self, index=True, deep=False):
25632563
v += self.index.memory_usage(deep=deep)
25642564
return v
25652565

2566-
def take(self, indices, axis=0, convert=True, is_copy=False, **kwargs):
2567-
"""
2568-
return Series corresponding to requested indices
2569-
2570-
Parameters
2571-
----------
2572-
indices : list / array of ints
2573-
convert : translate negative to positive indices (default)
2574-
2575-
Returns
2576-
-------
2577-
taken : Series
2578-
2579-
See also
2580-
--------
2581-
numpy.ndarray.take
2582-
"""
2583-
if kwargs:
2584-
nv.validate_take(tuple(), kwargs)
2585-
2586-
# check/convert indicies here
2566+
@Appender(generic._shared_docs['_take'])
2567+
def _take(self, indices, axis=0, convert=True, is_copy=False):
25872568
if convert:
25882569
indices = maybe_convert_indices(indices, len(self._get_axis(axis)))
25892570

25902571
indices = _ensure_platform_int(indices)
25912572
new_index = self.index.take(indices)
25922573
new_values = self._values.take(indices)
2593-
return (self._constructor(new_values, index=new_index, fastpath=True)
2594-
.__finalize__(self))
2574+
2575+
result = (self._constructor(new_values, index=new_index,
2576+
fastpath=True).__finalize__(self))
2577+
2578+
# Maybe set copy if we didn't actually change the index.
2579+
if is_copy:
2580+
if not result._get_axis(axis).equals(self._get_axis(axis)):
2581+
result._set_is_copy(self)
2582+
2583+
return result
25952584

25962585
def isin(self, values):
25972586
"""

Diff for: 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)