Skip to content

Commit

Permalink
BUG: is_scalar_indexer (pandas-dev#32850)
Browse files Browse the repository at this point in the history
* BUG: is_scalar_indexer

* update docstring

* add copy=False
  • Loading branch information
jbrockmendel authored and SeeminSyed committed Mar 22, 2020
1 parent 065accb commit f810831
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
18 changes: 13 additions & 5 deletions pandas/core/indexers.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,26 @@ def is_list_like_indexer(key) -> bool:
return is_list_like(key) and not (isinstance(key, tuple) and type(key) is not tuple)


def is_scalar_indexer(indexer, arr_value) -> bool:
def is_scalar_indexer(indexer, ndim: int) -> bool:
"""
Return True if we are all scalar indexers.
Parameters
----------
indexer : object
ndim : int
Number of dimensions in the object being indexed.
Returns
-------
bool
"""
if arr_value.ndim == 1:
if not isinstance(indexer, tuple):
indexer = tuple([indexer])
return any(isinstance(idx, np.ndarray) and len(idx) == 0 for idx in indexer)
if isinstance(indexer, tuple):
if len(indexer) == ndim:
return all(
is_integer(x) or (isinstance(x, np.ndarray) and x.ndim == len(x) == 1)
for x in indexer
)
return False


Expand Down
8 changes: 3 additions & 5 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ def setitem(self, indexer, value):
# GH#8669 empty indexers
pass

elif is_scalar_indexer(indexer, arr_value):
elif is_scalar_indexer(indexer, self.ndim):
# setting a single element for each dim and with a rhs that could
# be e.g. a list; see GH#6043
values[indexer] = value
Expand All @@ -892,12 +892,10 @@ def setitem(self, indexer, value):
# if we are an exact match (ex-broadcasting),
# then use the resultant dtype
elif exact_match:
# We are setting _all_ of the array's values, so can cast to new dtype
values[indexer] = value

try:
values = values.astype(arr_value.dtype)
except ValueError:
pass
values = values.astype(arr_value.dtype, copy=False)

# set
else:
Expand Down
19 changes: 18 additions & 1 deletion pandas/tests/indexing/test_indexers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
# Tests aimed at pandas.core.indexers
import numpy as np

from pandas.core.indexers import length_of_indexer
from pandas.core.indexers import is_scalar_indexer, length_of_indexer


def test_length_of_indexer():
arr = np.zeros(4, dtype=bool)
arr[0] = 1
result = length_of_indexer(arr)
assert result == 1


def test_is_scalar_indexer():
indexer = (0, 1)
assert is_scalar_indexer(indexer, 2)
assert not is_scalar_indexer(indexer[0], 2)

indexer = (np.array([2]), 1)
assert is_scalar_indexer(indexer, 2)

indexer = (np.array([2]), np.array([3]))
assert is_scalar_indexer(indexer, 2)

indexer = (np.array([2]), np.array([3, 4]))
assert not is_scalar_indexer(indexer, 2)

assert not is_scalar_indexer(slice(None), 1)

0 comments on commit f810831

Please sign in to comment.