def __getitem__(self, key): getitem = self._data.__getitem__ if np.isscalar(key): val = getitem(key) return self._box_func(val) else: if com.is_bool_indexer(key): key = np.asarray(key) if key.all(): key = slice(0, None, None) else: key = lib.maybe_booleans_to_slice(key.view(np.uint8)) attribs = self._get_attributes_dict() freq = None if isinstance(key, slice): if self.freq is not None and key.step is not None: freq = key.step * self.freq else: freq = self.freq attribs['freq'] = freq result = getitem(key) if result.ndim > 1: return result return self._simple_new(result, **attribs)
def test_mask_with_boolean(index): s = Series(range(3)) idx = Categorical([True, False, True]) if index: idx = CategoricalIndex(idx) assert com.is_bool_indexer(idx) result = s[idx] expected = s[idx.astype('object')] tm.assert_series_equal(result, expected)
def __getitem__(self, key): """ This getitem defers to the underlying array, which by-definition can only handle list-likes, slices, and integer scalars """ is_int = lib.is_integer(key) if lib.is_scalar(key) and not is_int: raise IndexError("only integers, slices (`:`), ellipsis (`...`), " "numpy.newaxis (`None`) and integer or boolean " "arrays are valid indices") getitem = self._data.__getitem__ if is_int: val = getitem(key) return self._box_func(val) if com.is_bool_indexer(key): key = np.asarray(key, dtype=bool) if key.all(): key = slice(0, None, None) else: key = lib.maybe_booleans_to_slice(key.view(np.uint8)) attribs = self._get_attributes_dict() is_period = is_period_dtype(self) if is_period: freq = self.freq else: freq = None if isinstance(key, slice): if self.freq is not None and key.step is not None: freq = key.step * self.freq else: freq = self.freq elif key is Ellipsis: # GH#21282 indexing with Ellipsis is similar to a full slice, # should preserve `freq` attribute freq = self.freq attribs['freq'] = freq result = getitem(key) if result.ndim > 1: # To support MPL which performs slicing with 2 dim # even though it only has 1 dim by definition if is_period: return self._simple_new(result, **attribs) return result return self._simple_new(result, **attribs)
def __getitem__(self, key): """ This getitem defers to the underlying array, which by-definition can only handle list-likes, slices, and integer scalars """ is_int = is_integer(key) if is_scalar(key) and not is_int: raise ValueError getitem = self._data.__getitem__ if is_int: val = getitem(key) return self._box_func(val) else: if com.is_bool_indexer(key): key = np.asarray(key) if key.all(): key = slice(0, None, None) else: key = lib.maybe_booleans_to_slice(key.view(np.uint8)) attribs = self._get_attributes_dict() is_period = isinstance(self, ABCPeriodIndex) if is_period: freq = self.freq else: freq = None if isinstance(key, slice): if self.freq is not None and key.step is not None: freq = key.step * self.freq else: freq = self.freq attribs['freq'] = freq result = getitem(key) if result.ndim > 1: # To support MPL which performs slicing with 2 dim # even though it only has 1 dim by definition if is_period: return self._simple_new(result, **attribs) return result return self._simple_new(result, **attribs)
def __getitem__(self, key): getitem = self._data.__getitem__ if np.isscalar(key): val = getitem(key) return Timedelta(val) else: if com.is_bool_indexer(key): key = np.asarray(key) if key.all(): key = slice(0,None,None) else: key = lib.maybe_booleans_to_slice(key.view(np.uint8)) result = getitem(key) if result.ndim > 1: return result return self._simple_new(result, self.name)
def __getitem__(self, key): getitem = self._data.__getitem__ if is_scalar(key): val = getitem(key) return Period(ordinal=val, freq=self.freq) else: if com.is_bool_indexer(key): key = np.asarray(key) result = getitem(key) if result.ndim > 1: # MPL kludge # values = np.asarray(list(values), dtype=object) # return values.reshape(result.shape) return PeriodIndex(result, name=self.name, freq=self.freq) return PeriodIndex(result, name=self.name, freq=self.freq)
def __setitem__( self, key, # type: Union[int, Sequence[int], Sequence[bool], slice] value # type: Union[NaTType, Period, Sequence[Period]] ): # type: (...) -> None # n.b. the type on `value` is a bit too restrictive. # we also accept a sequence of stuff coercible to a PeriodArray # by period_array, which includes things like ndarray[object], # ndarray[datetime64ns]. I think ndarray[int] / ndarray[str] won't # work, since the freq can't be inferred. if is_list_like(value): is_slice = isinstance(key, slice) if (not is_slice and len(key) != len(value) and not com.is_bool_indexer(key)): msg = ("shape mismatch: value array of length '{}' does not " "match indexing result of length '{}'.") raise ValueError(msg.format(len(key), len(value))) if not is_slice and len(key) == 0: return value = period_array(value) if self.freqstr != value.freqstr: msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, value.freqstr) raise IncompatibleFrequency(msg) value = value.asi8 elif isinstance(value, Period): if self.freqstr != value.freqstr: msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, value.freqstr) raise IncompatibleFrequency(msg) value = value.ordinal elif isna(value): value = iNaT else: msg = ("'value' should be a 'Period', 'NaT', or array of those. " "Got '{}' instead.".format(type(value).__name__)) raise TypeError(msg) self._data[key] = value
def get_value(self, series, key): if com.is_bool_indexer(key): loc = key elif is_list_like(key): loc = self.get_indexer(key) elif isinstance(key, slice): if not (key.step is None or key.step == 1): raise ValueError("cannot support not-default step in a slice") try: loc = self.get_loc(key) except TypeError: # we didn't find exact intervals or are non-unique msg = "unable to slice with this key: {key}".format(key=key) raise ValueError(msg) else: loc = self.get_loc(key) return series.iloc[loc]
def __getitem__(self, key): if isinstance(key, tuple): if len(key) > 1: raise IndexError("too many indices for array.") key = key[0] if is_integer(key): return self._get_val_at(key) elif isinstance(key, tuple): data_slice = self.values[key] elif isinstance(key, slice): # special case to preserve dtypes if key == slice(None): return self.copy() # TODO: this logic is surely elsewhere # TODO: this could be more efficient indices = np.arange(len(self), dtype=np.int32)[key] return self.take(indices) else: # TODO: I think we can avoid densifying when masking a # boolean SparseArray with another. Need to look at the # key's fill_value for True / False, and then do an intersection # on the indicies of the sp_values. if isinstance(key, SparseArray): if is_bool_dtype(key): key = key.to_dense() else: key = np.asarray(key) if com.is_bool_indexer(key) and len(self) == len(key): # TODO(numpy 1.11): Remove this asarray. # Old NumPy didn't treat array-like as boolean masks. key = np.asarray(key) return self.take(np.arange(len(key), dtype=np.int32)[key]) elif hasattr(key, '__len__'): return self.take(key) else: raise ValueError("Cannot slice with '{}'".format(key)) return type(self)(data_slice, kind=self.kind)
def get_value(self, series, key): if com.is_bool_indexer(key): loc = key elif is_list_like(key): loc = self.get_indexer(key) elif isinstance(key, slice): if not (key.step is None or key.step == 1): raise ValueError("cannot support not-default " "step in a slice") try: loc = self.get_loc(key) except TypeError: # we didn't find exact intervals # or are non-unique raise ValueError("unable to slice with " "this key: {}".format(key)) else: loc = self.get_loc(key) return series.iloc[loc]
def __getitem__(self, key): if isinstance(key, tuple): if len(key) > 1: raise IndexError("too many indices for array.") key = key[0] if is_integer(key): return self._get_val_at(key) elif isinstance(key, tuple): data_slice = self.to_dense()[key] elif isinstance(key, slice): # special case to preserve dtypes if key == slice(None): return self.copy() # TODO: this logic is surely elsewhere # TODO: this could be more efficient indices = np.arange(len(self), dtype=np.int32)[key] return self.take(indices) else: # TODO: I think we can avoid densifying when masking a # boolean SparseArray with another. Need to look at the # key's fill_value for True / False, and then do an intersection # on the indicies of the sp_values. if isinstance(key, SparseArray): if is_bool_dtype(key): key = key.to_dense() else: key = np.asarray(key) if com.is_bool_indexer(key) and len(self) == len(key): return self.take(np.arange(len(key), dtype=np.int32)[key]) elif hasattr(key, "__len__"): return self.take(key) else: raise ValueError("Cannot slice with '{}'".format(key)) return type(self)(data_slice, kind=self.kind)
def __getitem__(self, key): """ This getitem defers to the underlying array, which by-definition can only handle list-likes, slices, and integer scalars """ is_int = is_integer(key) if lib.isscalar(key) and not is_int: raise ValueError getitem = self._data.__getitem__ if is_int: val = getitem(key) return self._box_func(val) else: if com.is_bool_indexer(key): key = np.asarray(key) if key.all(): key = slice(0, None, None) else: key = lib.maybe_booleans_to_slice(key.view(np.uint8)) attribs = self._get_attributes_dict() freq = None if isinstance(key, slice): if self.freq is not None and key.step is not None: freq = key.step * self.freq else: freq = self.freq attribs["freq"] = freq result = getitem(key) if result.ndim > 1: return result return self._simple_new(result, **attribs)
def get_loc(self, key, method=None, tolerance=None): """ Get integer location for requested label Returns ------- loc : int """ if is_bool_indexer(key): raise TypeError if isnull(key): key = tslib.NaT if tolerance is not None: # try converting tolerance now, so errors don't get swallowed by # the try/except clauses below tolerance = self._convert_tolerance(tolerance) if _is_convertible_to_td(key): key = Timedelta(key) return Index.get_loc(self, key, method, tolerance) try: return Index.get_loc(self, key, method, tolerance) except (KeyError, ValueError, TypeError): try: return self._get_string_slice(key) except (TypeError, KeyError, ValueError): pass try: stamp = Timedelta(key) return Index.get_loc(self, stamp, method, tolerance) except (KeyError, ValueError): raise KeyError(key)
def get_loc(self, key, method=None, tolerance=None): """ Get integer location for requested label Returns ------- loc : int """ if is_bool_indexer(key): raise TypeError if isnull(key): key = NaT if tolerance is not None: # try converting tolerance now, so errors don't get swallowed by # the try/except clauses below tolerance = self._convert_tolerance(tolerance) if _is_convertible_to_td(key): key = Timedelta(key) return Index.get_loc(self, key, method, tolerance) try: return Index.get_loc(self, key, method, tolerance) except (KeyError, ValueError, TypeError): try: return self._get_string_slice(key) except (TypeError, KeyError, ValueError): pass try: stamp = Timedelta(key) return Index.get_loc(self, stamp, method, tolerance) except (KeyError, ValueError): raise KeyError(key)
def __getitem__(self, key): """ This getitem defers to the underlying array, which by-definition can only handle list-likes, slices, and integer scalars """ is_int = is_integer(key) if lib.isscalar(key) and not is_int: raise ValueError getitem = self._data.__getitem__ if is_int: val = getitem(key) return self._box_func(val) else: if com.is_bool_indexer(key): key = np.asarray(key) if key.all(): key = slice(0, None, None) else: key = lib.maybe_booleans_to_slice(key.view(np.uint8)) attribs = self._get_attributes_dict() freq = None if isinstance(key, slice): if self.freq is not None and key.step is not None: freq = key.step * self.freq else: freq = self.freq attribs['freq'] = freq result = getitem(key) if result.ndim > 1: return result return self._simple_new(result, **attribs)
def test_non_bool_array_with_na(self): # in particular, this should not raise arr = np.array(["A", "B", np.nan]) assert not com.is_bool_indexer(arr)
def __getitem__(self, key): """ Get subsection of self using given key Parameters ---------- key : int or slice or boolean indexer or tuple of 2 ints/ slices! Returns ------- XLCell or XLRange result after selection using key applied. Designed to emulate behaviour of Pandas Indexes. Notes ----- int, single slice and boolean indexers can only be used on one dimensional XLRanges. Will always return an XLRange unless a scalar key is used. """ if is_int_type(key): if not self.is_1D: raise TypeError("Can only do integer lookups on 1D ranges") elif key < 0: key += len(self) if self.is_row: return self.start.translate(0, key) else: return self.start.translate(key, 0) elif isinstance(key, slice): key = fill_slice(key) if key.step != 1: raise TypeError("Can only slice with step equal to 1") start, stop = key.start, (key.stop) return self[start] - self[stop] elif is_bool_indexer(key): if not self.is_1D: raise TypeError("Can only use Boolean indexers on 1D ranges") true_positions = list(i for i, bool_ in enumerate(key) if bool_ == True) start = min(true_positions) stop = max(true_positions) step_is_1 = ((stop - start) + 1) / len(true_positions) == 1 if not step_is_1: raise TypeError( "Bool indexers can't have any holes in (i.e. equivalent as slice must have step=1)" ) return self[start:stop] elif len(key) == 2: if self.is_1D: raise TypeError( "2 Parameter indexing only available on 2D ranges") row_slice, col_slice = key if is_int_type(row_slice) and is_int_type(col_slice): if row_slice < 0: row_slice += self.shape[0] if col_slice < 0: col_slice += self.shape[1] return self.start.translate(row_slice, col_slice) elif isinstance(row_slice, slice) and isinstance(col_slice, slice): row_slice = fill_slice(row_slice) col_slice = fill_slice(col_slice) row_stop = row_slice.stop if row_slice.stop < 0: row_stop += self.shape[0] col_stop = col_slice.stop if col_slice.stop < 0: col_stop += self.shape[1] return XLRange( self.start.translate(row_slice.start, col_slice.start), self.start.translate(row_stop, col_stop)) raise TypeError( "Expecting tuple of slices, boolean indexer, or an index or a slice if 1D, not {}" .format(key))
def __getitem__(self, key): from pandas.core.dtypes.common import is_list_like, is_integer, is_iterator key = com.apply_if_callable(key, self) # shortcut if the key is in columns try: if self.columns.is_unique and key in self.columns: if self.columns.nlevels > 1: return self._getitem_multilevel(key) return self._get_item_cache(key) except (TypeError, ValueError): # The TypeError correctly catches non hashable "key" (e.g. list) # The ValueError can be removed once GH #21729 is fixed pass # Do we have a slicer (on rows)? indexer = convert_to_index_sliceable(self, key) if indexer is not None: return self._slice(indexer, axis=0) # Do we have a (boolean) DataFrame? if isinstance(key, DataFrame): return self._getitem_frame(key) # Do we have a (boolean) 1d indexer? if com.is_bool_indexer(key): return self._getitem_bool_array(key) # We are left with two options: a single key, and a collection of keys, # We interpret tuples as collections only for non-MultiIndex is_single_key = isinstance(key, tuple) or not is_list_like(key) if is_single_key: if self.columns.nlevels > 1: return self._getitem_multilevel(key) indexer = self.columns.get_loc(key) if is_integer(indexer): indexer = [indexer] else: if is_iterator(key): key = list(key) # noinspection PyProtectedMember indexer = self.loc._convert_to_indexer(key, axis=1, raise_missing=True) # take() does not accept boolean indexers if getattr(indexer, "dtype", None) == bool: indexer = np.where(indexer)[0] data = self._take(indexer, axis=1) if is_single_key: # What does looking for a single key in a non-unique index return? # The behavior is inconsistent. It returns a Series, except when # - the key itself is repeated (test on data.shape, #9519), or # - we have a MultiIndex on columns (test on self.columns, #21309) if data.shape[1] == 1 and not isinstance(self.columns, MultiIndex): data = data[key] return data