Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAugspurger committed Dec 19, 2019
1 parent 3dd59ca commit 151bdfe
Show file tree
Hide file tree
Showing 10 changed files with 26 additions and 20 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,7 @@ Datetimelike
- Bug in :attr:`Timestamp.resolution` being a property instead of a class attribute (:issue:`29910`)
- Bug in :func:`pandas.to_datetime` when called with ``None`` raising ``TypeError`` instead of returning ``NaT`` (:issue:`30011`)
- Bug in :func:`pandas.to_datetime` failing for `deques` when using ``cache=True`` (the default) (:issue:`29403`)
- Bug in datetimelike indexes and arrays not validating that the length of a boolean mask matches the array (:issue:`30308`)
- Bug in :meth:`Series.item` with ``datetime64`` or ``timedelta64`` dtype, :meth:`DatetimeIndex.item`, and :meth:`TimedeltaIndex.item` returning an integer instead of a :class:`Timestamp` or :class:`Timedelta` (:issue:`30175`)
-

Expand Down
4 changes: 3 additions & 1 deletion pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,9 @@ def __getitem__(self, key):
return self._box_func(val)

if com.is_bool_indexer(key):
key = np.asarray(key, dtype=bool)
from pandas.core.indexing import check_bool_indexer

key = check_bool_indexer(self, key)
if key.all():
key = slice(0, None, None)
else:
Expand Down
19 changes: 6 additions & 13 deletions pandas/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,35 +112,28 @@ def is_bool_indexer(key: Any) -> bool:
bool
Whether `key` is a valid boolean indexer.
Raises
------
ValueError
When the array is an object-dtype ndarray or ExtensionArray
and contains missing values.
Notes
-----
This function is inexpensive for `bool` and `BooleanDtype`.
It is expensive for object-dtype backed arrays. In this case
a scan of the data to check that all the values are bool is
needed.
See Also
--------
api.extensions.check_bool_array_indexer : Check that `key`
is a valid mask for an array, and convert to an ndarary.
"""
na_msg = "cannot index with vector containing NA / NaN values"
if isinstance(key, (ABCSeries, np.ndarray, ABCIndex)) or (
is_array_like(key) and is_extension_array_dtype(key.dtype)
):
if key.dtype == np.object_:
key = np.asarray(values_from_object(key))

if not lib.is_bool_array(key):
if isna(key).any():
raise ValueError(na_msg)
return False
return True
elif is_bool_dtype(key.dtype):
# an ndarray with bool-dtype by definition has no missing values.
# So we only need to check for NAs in ExtensionArrays
if is_extension_array_dtype(key.dtype):
if np.any(key.isna()):
raise ValueError(na_msg)
return True
elif isinstance(key, list):
try:
Expand Down
4 changes: 0 additions & 4 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -2799,10 +2799,6 @@ def _setitem_slice(self, key, value):
def _setitem_array(self, key, value):
# also raises Exception if object array with NA values
if com.is_bool_indexer(key):
if len(key) != len(self.index):
raise ValueError(
f"Item wrong length {len(key)} instead of {len(self.index)}!"
)
key = check_bool_indexer(self.index, key)
indexer = key.nonzero()[0]
self._check_setitem_copy()
Expand Down
4 changes: 3 additions & 1 deletion pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3998,6 +3998,8 @@ def __getitem__(self, key):
corresponding `Index` subclass.
"""
from pandas.core.indexing import check_bool_indexer

# There's no custom logic to be implemented in __getslice__, so it's
# not overloaded intentionally.
getitem = self._data.__getitem__
Expand All @@ -4013,7 +4015,7 @@ def __getitem__(self, key):
return promote(getitem(key))

if com.is_bool_indexer(key):
key = np.asarray(key, dtype=bool)
key = check_bool_indexer(self, key)

key = com.values_from_object(key)
result = getitem(key)
Expand Down
2 changes: 2 additions & 0 deletions pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,8 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None):
_has_same_tz = ea_passthrough(DatetimeArray._has_same_tz)

def __getitem__(self, key):
# if com.is_bool_indexer(key):
# breakpoint()
result = self._data.__getitem__(key)
if is_scalar(result):
return result
Expand Down
3 changes: 2 additions & 1 deletion pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
ensure_index,
)
from pandas.core.indexes.frozen import FrozenList
from pandas.core.indexing import check_bool_indexer
import pandas.core.missing as missing
from pandas.core.sorting import (
get_group_index,
Expand Down Expand Up @@ -1934,7 +1935,7 @@ def __getitem__(self, key):
return tuple(retval)
else:
if com.is_bool_indexer(key):
key = np.asarray(key, dtype=bool)
key = check_bool_indexer(self, key)
sortorder = self.sortorder
else:
# cannot be sure whether the result will be sorted
Expand Down
3 changes: 3 additions & 0 deletions pandas/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,7 @@ def _validate_key(self, key, axis: int):
return

if com.is_bool_indexer(key):
# XXX: do we need to verify no NA here?
return

if not is_list_like_indexer(key):
Expand Down Expand Up @@ -1681,6 +1682,7 @@ def _getitem_axis(self, key, axis: int):
self._validate_key(key, axis)
return self._get_slice_axis(key, axis=axis)
elif com.is_bool_indexer(key):
# check_bool_indexer is called in getbool_axis
return self._getbool_axis(key, axis=axis)
elif is_list_like_indexer(key):

Expand Down Expand Up @@ -2030,6 +2032,7 @@ def _getitem_axis(self, key, axis: int):
key = np.asarray(key)

if com.is_bool_indexer(key):
# check_bool_indexer is called in _getbool_axis
self._validate_key(key, axis)
return self._getbool_axis(key, axis=axis)

Expand Down
1 change: 1 addition & 0 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ def __getitem__(self, key):
elif key is Ellipsis:
return self
elif com.is_bool_indexer(key):
# We check later on.
pass
else:

Expand Down
5 changes: 5 additions & 0 deletions pandas/tests/indexes/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ def test_get_indexer_consistency(self, indices):
assert isinstance(indexer, np.ndarray)
assert indexer.dtype == np.intp

def test_getitem_mask_wrong_length(self, indices):
mask = np.array([True])
with pytest.raises(IndexError, match="Item wrong length 1"):
indices[mask]

def test_ndarray_compat_properties(self):
idx = self.create_index()
assert idx.T.equals(idx)
Expand Down

0 comments on commit 151bdfe

Please sign in to comment.