Skip to content

REF: setitem_with_indexer DataFrame always go through split_path #40380

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

Closed
wants to merge 103 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
2c761eb
REF: setitem_with_indexer always use same path for 2D
jbrockmendel Dec 28, 2020
d207a12
Merge branch 'master' of https://github.com/pandas-dev/pandas into re…
jbrockmendel Jan 6, 2021
f0dae4d
Merge branch 'master' of https://github.com/pandas-dev/pandas into re…
jbrockmendel Jan 8, 2021
27bd89d
fixed xfail
jbrockmendel Jan 8, 2021
a5c1f5e
REF: DataFrame._setitem_array dont use iloc.__setitem__
jbrockmendel Jan 27, 2021
15f5265
REF: DataFrame._setitem_array dont use iloc.__setitem__
jbrockmendel Jan 31, 2021
73302c0
Merge branch 'master' of https://github.com/pandas-dev/pandas into se…
jbrockmendel Jan 31, 2021
ceeeb78
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Jan 31, 2021
6b304b8
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 2, 2021
fe9be7e
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 2, 2021
1789fca
mypy fixup
jbrockmendel Feb 2, 2021
6400be3
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 2, 2021
a1cdd19
mypy fixup
jbrockmendel Feb 2, 2021
870ae37
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 2, 2021
c32a427
32bit compat
jbrockmendel Feb 2, 2021
d9d8beb
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 2, 2021
8a283d9
troubleshoot windows builds
jbrockmendel Feb 2, 2021
9718f6e
Merge branch 'master' of https://github.com/pandas-dev/pandas into se…
jbrockmendel Feb 3, 2021
9f6d8e7
troubleshoot 32bit
jbrockmendel Feb 3, 2021
dd53abc
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 3, 2021
f6b09b4
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 7, 2021
c107e77
TST: missed raising cases
jbrockmendel Feb 7, 2021
ae3ae1b
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 18, 2021
c631079
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 23, 2021
4cfe863
port phofl tests
jbrockmendel Feb 23, 2021
03e6eb9
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 25, 2021
d280f60
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 26, 2021
9db5537
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 27, 2021
4054aea
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Feb 27, 2021
bd76479
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Mar 4, 2021
7ea792f
whatsnew
jbrockmendel Mar 4, 2021
20f6a16
clarify whatsnew
jbrockmendel Mar 4, 2021
b9daceb
merge but not passing...
jbrockmendel Mar 5, 2021
6117e8e
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 5, 2021
94b33a8
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 5, 2021
8f71f27
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 5, 2021
17049e4
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 6, 2021
fdbf6f3
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Mar 7, 2021
f8363f9
Merge branch 'setitem-frame-no-defer' into ref-indexing-2
jbrockmendel Mar 7, 2021
2c6da5d
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Mar 8, 2021
2d0cf9e
comment
jbrockmendel Mar 8, 2021
e1ed083
whatsnew
jbrockmendel Mar 8, 2021
df9d87f
checkpoint passing
jbrockmendel Mar 9, 2021
aeb687c
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 9, 2021
481ece1
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 9, 2021
95f34c8
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 11, 2021
be54f15
Fix dtype in loc-setitem-with-expansion
jbrockmendel Mar 11, 2021
6896e86
Merge branch 'master' into setitem-frame-no-defer
jbrockmendel Mar 12, 2021
b183084
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 12, 2021
fa2006b
ArrayManager compat
jbrockmendel Mar 12, 2021
1af8686
xfail only for BM
jbrockmendel Mar 13, 2021
301d582
Merge branch 'setitem-frame-no-defer' into ref-indexing-2
jbrockmendel Mar 13, 2021
1d24f71
mypy fixup
jbrockmendel Mar 13, 2021
d8c7c4c
special case ArrayManager
jbrockmendel Mar 13, 2021
f0037e6
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 15, 2021
094e47d
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 17, 2021
6791a97
ArrayManager compat
jbrockmendel Mar 17, 2021
d01951d
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 22, 2021
01ff673
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 24, 2021
8e8e711
arraymanager compat for tests
jbrockmendel Mar 24, 2021
18d72ec
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 31, 2021
ba1d17c
Merge branch 'master' into ref-indexing-2
jbrockmendel Mar 31, 2021
1fca2d5
Merge branch 'master' into ref-indexing-2
jbrockmendel Apr 1, 2021
1382985
Merge branch 'master' into ref-indexing-2
jbrockmendel Apr 2, 2021
10ab24d
merge master
jbrockmendel Apr 2, 2021
8e5a414
Merge branch 'master' into ref-indexing-2
jbrockmendel Apr 3, 2021
cdfc811
Merge branch 'master' into ref-indexing-2
jbrockmendel Apr 7, 2021
d761df6
Merge branch 'master' into ref-indexing-2
jbrockmendel Apr 12, 2021
b4d0211
Merge branch 'master' into ref-indexing-2
jbrockmendel Apr 16, 2021
53be486
Merge branch 'master' into ref-indexing-2
jbrockmendel May 10, 2021
05107a2
Merge branch 'master' into ref-indexing-2
jbrockmendel May 12, 2021
b87fc55
Merge branch 'master' into ref-indexing-2
jbrockmendel Jun 4, 2021
3279159
Merge branch 'master' into ref-indexing-2
jbrockmendel Jun 16, 2021
9f7e274
Merge branch 'master' into ref-indexing-2
jbrockmendel Jun 24, 2021
a4aed44
Merge branch 'master' into ref-indexing-2
jbrockmendel Jul 24, 2021
e1c30fa
Merge branch 'master' of https://github.com/pandas-dev/pandas into re…
jbrockmendel Jul 29, 2021
e062dce
Merge branch 'master' into ref-indexing-2
jbrockmendel Jul 30, 2021
9a73ef6
update incorrect tests
jbrockmendel Jul 30, 2021
4a9919b
Merge remote-tracking branch 'upstream/master' into ref-indexing-2
jbrockmendel Jul 30, 2021
8761ffa
docstring, comment
jbrockmendel Jul 31, 2021
99e3316
Merge remote-tracking branch 'upstream/master' into ref-indexing-2
jbrockmendel Jul 31, 2021
be22a99
Merge branch 'master' into ref-indexing-2
jbrockmendel Aug 4, 2021
86d3e71
Merge branch 'master' into ref-indexing-2
jbrockmendel Aug 17, 2021
d49512b
Merge branch 'master' into ref-indexing-2
jbrockmendel Aug 23, 2021
d821e8b
REF: implement mask_setitem_value
jbrockmendel Sep 18, 2021
f142f16
Merge branch 'master' into ref-indexing-2
jbrockmendel Sep 18, 2021
eccfebb
Merge branch 'ref-indexing-bool' into ref-indexing-2
jbrockmendel Sep 18, 2021
0c430c9
Merge branch 'master' into ref-indexing-2
jbrockmendel Sep 30, 2021
295737e
Merge branch 'master' into ref-indexing-2
jbrockmendel Oct 4, 2021
405b21f
Merge branch 'master' into ref-indexing-2
jbrockmendel Oct 19, 2021
520230c
Merge branch 'master' into ref-indexing-2
jbrockmendel Oct 19, 2021
0ac5516
fix last tesst
jbrockmendel Oct 19, 2021
7a46ab8
Merge branch 'master' into ref-indexing-2
jbrockmendel Oct 31, 2021
b19a787
Merge branch 'master' into ref-indexing-2
jbrockmendel Nov 1, 2021
7bf721b
Merge branch 'master' into ref-indexing-2
jbrockmendel Nov 1, 2021
7db1a5a
ArrayManager cases
jbrockmendel Nov 1, 2021
ca0f516
Merge branch 'master' into ref-indexing-2
jbrockmendel Nov 7, 2021
3b456f9
remove _isetitem
jbrockmendel Nov 7, 2021
1e4b617
Merge branch 'master' into ref-indexing-2
jbrockmendel Nov 9, 2021
1d203a6
Merge branch 'master' into ref-indexing-2
jbrockmendel Nov 29, 2021
4e69970
fixup missing fixture
jbrockmendel Nov 29, 2021
0a0e712
un-xfail for ArrayManager
jbrockmendel Nov 30, 2021
4ce2cd3
fix incorrect test
jbrockmendel Nov 30, 2021
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
4 changes: 3 additions & 1 deletion pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -5313,7 +5313,9 @@ def _replace_columnwise(
target, value = mapping[ax[i]]
newobj = ser.replace(target, value, regex=regex)

res.iloc[:, i] = newobj
# If we had unique columns, we could just do
# res[res.columns[i]] = newobj
res._iset_item_mgr(i, newobj._values)

if inplace:
return
Expand Down
186 changes: 143 additions & 43 deletions pandas/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from pandas._libs.indexing import NDFrameIndexerBase
from pandas._libs.lib import item_from_zerodim
from pandas._typing import Shape
from pandas.errors import (
AbstractMethodError,
InvalidIndexError,
Expand Down Expand Up @@ -634,12 +635,12 @@ def __call__(self, axis=None):
new_self.axis = axis
return new_self

def _get_setitem_indexer(self, key):
def _get_setitem_indexer(self, key, value):
"""
Convert a potentially-label-based key into a positional indexer.
"""
if self.name == "loc":
self._ensure_listlike_indexer(key)
self._ensure_listlike_indexer(key, value=value)

if self.axis is not None:
return self._convert_tuple(key)
Expand Down Expand Up @@ -677,9 +678,11 @@ def _ensure_listlike_indexer(self, key, axis=None, value=None):
if self.ndim != 2:
return

pi = None
if isinstance(key, tuple) and len(key) > 1:
# key may be a tuple if we are .loc
# if length of key is > 1 set key to column part
pi = key[0]
key = key[column_axis]
axis = column_axis

Expand All @@ -693,17 +696,26 @@ def _ensure_listlike_indexer(self, key, axis=None, value=None):
# GH#38148
keys = self.obj.columns.union(key, sort=False)

self.obj._mgr = self.obj._mgr.reindex_axis(
keys, axis=0, consolidate=False, only_slice=True
)
if isinstance(value, ABCDataFrame) and com.is_null_slice(pi):
# We are setting obj.loc[:, new_keys] = newframe
# Setting these directly instead of reindexing keeps
# us from converting integer dtypes to floats
new_keys = keys.difference(self.obj.columns)
self.obj[new_keys] = value[new_keys]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't have __setitem__ a different behaviour as .loc ? (regarding replacing / updating inplace)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does, but only when the keys are already present in frame.columns. In this case we are only setting for non-present keys


else:

self.obj._mgr = self.obj._mgr.reindex_axis(
keys, axis=0, consolidate=False, only_slice=True
)

def __setitem__(self, key, value):
if isinstance(key, tuple):
key = tuple(list(x) if is_iterator(x) else x for x in key)
key = tuple(com.apply_if_callable(x, self.obj) for x in key)
else:
key = com.apply_if_callable(key, self.obj)
indexer = self._get_setitem_indexer(key)
indexer = self._get_setitem_indexer(key, value)
self._has_valid_setitem_indexer(key)

iloc = self if self.name == "iloc" else self.obj.iloc
Expand Down Expand Up @@ -1271,9 +1283,10 @@ def _convert_to_indexer(self, key, axis: int):
key = list(key)

if com.is_bool_indexer(key):
# TODO: in this case should we do a .take on the value here?
# test_loc_setitem_all_false_boolean_two_blocks
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phofl could use some extra eyeballs when convenient. I've got this down to one failing test where we have an all-False mask indexer. we need to do something like

if value_is_arraylike_etc:
     value = value[inds]

here, but not sure if this is the right place to do that

Copy link
Member

@phofl phofl Aug 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm no, I think we have to handle this case later.
Something like

df = DataFrame({"a": [1, 2], "b": [3, 4]})
df.loc[[], ["b"]] = 1

would not go through there but raises the same error currently because the indexer is empty too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do not have a test for this case, we should add one I think. This passes on master right now

key = check_bool_indexer(labels, key)
(inds,) = key.nonzero()
return inds
return key
else:
return self._get_listlike_indexer(key, axis)[1]
else:
Expand Down Expand Up @@ -1525,7 +1538,7 @@ def _convert_to_indexer(self, key, axis: int):
"""
return key

def _get_setitem_indexer(self, key):
def _get_setitem_indexer(self, key, value):
# GH#32257 Fall through to let numpy do validation
if is_iterator(key):
return list(key)
Expand All @@ -1547,32 +1560,6 @@ def _setitem_with_indexer(self, indexer, value, name="iloc"):
"""
info_axis = self.obj._info_axis_number

# maybe partial set
take_split_path = not self.obj._mgr.is_single_block

# if there is only one block/type, still have to take split path
# unless the block is one-dimensional or it can hold the value
if (
not take_split_path
and getattr(self.obj._mgr, "blocks", False)
and self.ndim > 1
):
# in case of dict, keys are indices
val = list(value.values()) if isinstance(value, dict) else value
blk = self.obj._mgr.blocks[0]
take_split_path = not blk._can_hold_element(val)

# if we have any multi-indexes that have non-trivial slices
# (not null slices) then we must take the split path, xref
# GH 10360, GH 27841
if isinstance(indexer, tuple) and len(indexer) == len(self.obj.axes):
for i, ax in zip(indexer, self.obj.axes):
if isinstance(ax, MultiIndex) and not (
is_integer(i) or com.is_null_slice(i)
):
take_split_path = True
break

if isinstance(indexer, tuple):
nindexer = []
for i, idx in enumerate(indexer):
Expand Down Expand Up @@ -1666,7 +1653,7 @@ def _setitem_with_indexer(self, indexer, value, name="iloc"):
return

# align and set the values
if take_split_path:
if self.ndim > 1:
# We have to operate column-wise
self._setitem_with_indexer_split_path(indexer, value, name)
else:
Expand All @@ -1679,23 +1666,65 @@ def _setitem_with_indexer_split_path(self, indexer, value, name: str):
# Above we only set take_split_path to True for 2D cases
assert self.ndim == 2

orig = indexer
if not isinstance(indexer, tuple):
indexer = _tuplify(self.ndim, indexer)
if len(indexer) > self.ndim:
raise IndexError("too many indices for array")
if isinstance(indexer[0], np.ndarray) and indexer[0].ndim > 2:
raise ValueError(r"Cannot set values with ndim > 2")

if (isinstance(value, ABCSeries) and name != "iloc") or isinstance(value, dict):
from pandas import Series

value = self._align_series(indexer, Series(value))

info_idx = indexer[1]
pi = indexer[0]
if (
isinstance(pi, ABCDataFrame)
and orig is pi
and hasattr(self.obj._mgr, "blocks")
and len(self.obj._mgr.blocks) == 1
):
# FIXME: kludge
return self._setitem_single_block(orig, value, name)

from pandas.core.internals import ArrayManager

if (
com.is_null_slice(info_idx)
and is_scalar(value)
and not isinstance(pi, ABCDataFrame)
and not isinstance(self.obj._mgr, ArrayManager)
):
# We can go directly through BlockManager.setitem without worrying
# about alignment.
# TODO: do we need to do some kind of copy_with_setting check?
self.obj._mgr = self.obj._mgr.setitem(indexer=indexer, value=value)
return

if is_integer(info_idx) and not isinstance(self.obj._mgr, ArrayManager):
if is_integer(pi):
# We need to watch out for case where we are treating a listlike
# as a scalar, e.g. test_setitem_iloc_scalar_single for JSONArray

mgr = self.obj._mgr
blkno = mgr.blknos[info_idx]
blkloc = mgr.blklocs[info_idx]
blk = mgr.blocks[blkno]

if blk._can_hold_element(value):
# NB: we are assuming here that _can_hold_element is accurate
# TODO: do we need to do some kind of copy_with_setting check?
self.obj._check_is_chained_assignment_possible()
blk.setitem_inplace((pi, blkloc), value)
self.obj._maybe_update_cacher(clear=True)
return

# Ensure we have something we can iterate over
info_axis = indexer[1]
ilocs = self._ensure_iterable_column_indexer(info_axis)

pi = indexer[0]
lplane_indexer = length_of_indexer(pi, self.obj.index)
# lplane_indexer gives the expected length of obj[indexer[0]]

Expand All @@ -1711,7 +1740,7 @@ def _setitem_with_indexer_split_path(self, indexer, value, name: str):

elif len(ilocs) == 1 and lplane_indexer == len(value) and not is_scalar(pi):
# We are setting multiple rows in a single column.
self._setitem_single_column(ilocs[0], value, pi)
self._setitem_iat_loc(ilocs[0], pi, value)

elif len(ilocs) == 1 and 0 != lplane_indexer != len(value):
# We are trying to set N values into M entries of a single
Expand Down Expand Up @@ -1739,7 +1768,7 @@ def _setitem_with_indexer_split_path(self, indexer, value, name: str):
elif len(ilocs) == len(value):
# We are setting multiple columns in a single row.
for loc, v in zip(ilocs, value):
self._setitem_single_column(loc, v, pi)
self._setitem_iat_loc(loc, pi, v)

elif len(ilocs) == 1 and com.is_null_slice(pi) and len(self.obj) == 0:
# This is a setitem-with-expansion, see
Expand Down Expand Up @@ -1777,6 +1806,7 @@ def _setitem_with_indexer_2d_value(self, indexer, value):

for i, loc in enumerate(ilocs):
# setting with a list, re-coerces
# self._setitem_iat_loc(loc, pi, value[:, i].tolist())
self._setitem_single_column(loc, value[:, i].tolist(), pi)

def _setitem_with_indexer_frame_value(self, indexer, value: DataFrame, name: str):
Expand All @@ -1793,7 +1823,7 @@ def _setitem_with_indexer_frame_value(self, indexer, value: DataFrame, name: str
if name == "iloc":
for i, loc in enumerate(ilocs):
val = value.iloc[:, i]
self._setitem_single_column(loc, val, pi)
self._setitem_iat_loc(loc, pi, val)

elif not unique_cols and value.columns.equals(self.obj.columns):
# We assume we are already aligned, see
Expand All @@ -1810,12 +1840,21 @@ def _setitem_with_indexer_frame_value(self, indexer, value: DataFrame, name: str
else:
val = np.nan

self._setitem_single_column(loc, val, pi)
self._setitem_iat_loc(loc, pi, val)

elif not unique_cols:
raise ValueError("Setting with non-unique columns is not allowed.")

else:
# TODO: not totally clear why we are requiring this
# Need so that we raise in test_multiindex_setitem
self._align_frame(indexer[0], value)

if com.is_bool_indexer(indexer[0]) and indexer[0].sum() == len(value):
# TODO: better place for this?
pi = indexer[0].nonzero()[0]
sub_indexer[0] = pi

for loc in ilocs:
item = self.obj.columns[loc]
if item in value:
Expand All @@ -1826,7 +1865,7 @@ def _setitem_with_indexer_frame_value(self, indexer, value: DataFrame, name: str
else:
val = np.nan

self._setitem_single_column(loc, val, pi)
self._setitem_iat_loc(loc, pi, val)

def _setitem_single_column(self, loc: int, value, plane_indexer):
"""
Expand All @@ -1839,6 +1878,7 @@ def _setitem_single_column(self, loc: int, value, plane_indexer):
The indexer we use for setitem along axis=0.
"""
pi = plane_indexer
pi, value = mask_setitem_value(pi, value, (len(self.obj),))

ser = self.obj._ixs(loc, axis=1)

Expand Down Expand Up @@ -1877,6 +1917,35 @@ def _setitem_single_column(self, loc: int, value, plane_indexer):
# reset the sliced object if unique
self.obj._iset_item(loc, ser)

def _setitem_iat_loc(self, loc: int, pi, value):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this method supposed to do? Can you add some docstring / comment?

# TODO: likely a BM method?
from pandas.core.internals import ArrayManager

if isinstance(self.obj._mgr, ArrayManager):
# TODO: implement this correctly for ArrayManager
return self._setitem_single_column(loc, value, pi)

mgr = self.obj._mgr
blkno = mgr.blknos[loc]
blkloc = mgr.blklocs[loc]
blk = mgr.blocks[blkno]
assert blk.mgr_locs[blkloc] == loc

if blk._can_hold_element(value):
# NB: we are assuming here that _can_hold_element is accurate
# TODO: do we need to do some kind of copy_with_setting check?
try:
self.obj._check_is_chained_assignment_possible()
blk.setitem_inplace((pi, blkloc), value)
self.obj._maybe_update_cacher(clear=True)
except ValueError:
if blk.is_extension:
# FIXME: kludge bc _can_hold_element is wrong for EABLock
return self._setitem_single_column(loc, value, pi)
raise
else:
self._setitem_single_column(loc, value, pi)

def _setitem_single_block(self, indexer, value, name: str):
"""
_setitem_with_indexer for the case when we have a single Block.
Expand Down Expand Up @@ -2442,3 +2511,34 @@ def need_slice(obj: slice) -> bool:
or obj.stop is not None
or (obj.step is not None and obj.step != 1)
)


def mask_setitem_value(indexer, value, shape: Shape):
"""
Convert a boolean indexer to a positional indexer, masking `value` if necessary.
"""
if com.is_bool_indexer(indexer):
indexer = np.asarray(indexer).nonzero()[0]
if is_list_like(value) and len(value) == shape[0]:
if not is_array_like(value):
value = [value[n] for n in indexer]
else:
value = value[indexer]

elif isinstance(indexer, tuple):
indexer = list(indexer)
for i, key in enumerate(indexer):
if com.is_bool_indexer(key):
new_key = np.asarray(key).nonzero()[0]
indexer[i] = new_key

if is_list_like(value) and len(value) == shape[i]:
# FIXME: assuming value.ndim == 1 here?
# FIXME: assuming non-i tuple member is scalar?
if not is_array_like(value):
value = [value[n] for n in new_key]
else:
value = value[new_key]

indexer = tuple(indexer)
return indexer, value
Loading