def _slice(self, slicer): """ Return a slice of myself. """ # only allow 1 dimensional slicing, but can # in a 2-d case be passd (slice(None),....) if isinstance(slicer, tuple) and len(slicer) == 2: if not _is_null_slice(slicer[0]): raise AssertionError("invalid slicing for a 1-ndim categorical") slicer = slicer[1] _codes = self._codes[slicer] return Categorical(values=_codes,levels=self.levels, ordered=self.ordered, name=self.name, fastpath=True)
def __setitem__(self, key, value): """ Item assignment. Raises ------ ValueError If (one or more) Value is not in levels or if a assigned `Categorical` has not the same levels """ # require identical level set if isinstance(value, Categorical): if not value.levels.equals(self.levels): raise ValueError( "cannot set a Categorical with another, without identical levels" ) rvalue = value if com.is_list_like(value) else [value] to_add = Index(rvalue) - self.levels if len(to_add): raise ValueError( "cannot setitem on a Categorical with a new level," " set the levels first") # set by position if isinstance(key, (int, np.integer)): pass # tuple of indexers elif isinstance(key, tuple): # only allow 1 dimensional slicing, but can # in a 2-d case be passd (slice(None),....) if len(key) == 2: if not _is_null_slice(key[0]): raise AssertionError( "invalid slicing for a 1-ndim categorical") key = key[1] elif len(key) == 1: key = key[0] else: raise AssertionError( "invalid slicing for a 1-ndim categorical") else: key = self._codes[key] lindexer = self.levels.get_indexer(rvalue) self._codes[key] = lindexer
def __setitem__(self, key, value): """ Item assignment. Raises ------ ValueError If (one or more) Value is not in levels or if a assigned `Categorical` has not the same levels """ # require identical level set if isinstance(value, Categorical): if not value.levels.equals(self.levels): raise ValueError("cannot set a Categorical with another, without identical levels") rvalue = value if com.is_list_like(value) else [value] to_add = Index(rvalue)-self.levels if len(to_add): raise ValueError("cannot setitem on a Categorical with a new level," " set the levels first") # set by position if isinstance(key, (int, np.integer)): pass # tuple of indexers elif isinstance(key, tuple): # only allow 1 dimensional slicing, but can # in a 2-d case be passd (slice(None),....) if len(key) == 2: if not _is_null_slice(key[0]): raise AssertionError("invalid slicing for a 1-ndim categorical") key = key[1] elif len(key) == 1: key = key[0] else: raise AssertionError("invalid slicing for a 1-ndim categorical") else: key = self._codes[key] lindexer = self.levels.get_indexer(rvalue) self._codes[key] = lindexer
def __setitem__(self, key, value): """ Item assignment. Raises ------ ValueError If (one or more) Value is not in categories or if a assigned `Categorical` has not the same categories """ # require identical categories set if isinstance(value, Categorical): if not value.categories.equals(self.categories): raise ValueError("Cannot set a Categorical with another, without identical " "categories") rvalue = value if com.is_list_like(value) else [value] to_add = Index(rvalue).difference(self.categories) # no assignments of values not in categories, but it's always ok to set something to np.nan if len(to_add) and not isnull(to_add).all(): raise ValueError("cannot setitem on a Categorical with a new category," " set the categories first") # set by position if isinstance(key, (int, np.integer)): pass # tuple of indexers (dataframe) elif isinstance(key, tuple): # only allow 1 dimensional slicing, but can # in a 2-d case be passd (slice(None),....) if len(key) == 2: if not _is_null_slice(key[0]): raise AssertionError("invalid slicing for a 1-ndim categorical") key = key[1] elif len(key) == 1: key = key[0] else: raise AssertionError("invalid slicing for a 1-ndim categorical") # slicing in Series or Categorical elif isinstance(key, slice): pass # Array of True/False in Series or Categorical else: # There is a bug in numpy, which does not accept a Series as a indexer # https://github.com/pydata/pandas/issues/6168 # https://github.com/numpy/numpy/issues/4240 -> fixed in numpy 1.9 # FIXME: remove when numpy 1.9 is the lowest numpy version pandas accepts... key = np.asarray(key) lindexer = self.categories.get_indexer(rvalue) # FIXME: the following can be removed after https://github.com/pydata/pandas/issues/7820 # is fixed. # float categories do currently return -1 for np.nan, even if np.nan is included in the # index -> "repair" this here if isnull(rvalue).any() and isnull(self.categories).any(): nan_pos = np.where(com.isnull(self.categories))[0] lindexer[lindexer == -1] = nan_pos self._codes[key] = lindexer
def __setitem__(self, key, value): """ Item assignment. Raises ------ ValueError If (one or more) Value is not in levels or if a assigned `Categorical` has not the same levels """ # require identical level set if isinstance(value, Categorical): if not value.levels.equals(self.levels): raise ValueError( "cannot set a Categorical with another, without identical levels" ) rvalue = value if com.is_list_like(value) else [value] to_add = Index(rvalue).difference(self.levels) # no assignments of values not in levels, but it's always ok to set something to np.nan if len(to_add) and not isnull(to_add).all(): raise ValueError( "cannot setitem on a Categorical with a new level," " set the levels first") # set by position if isinstance(key, (int, np.integer)): pass # tuple of indexers (dataframe) elif isinstance(key, tuple): # only allow 1 dimensional slicing, but can # in a 2-d case be passd (slice(None),....) if len(key) == 2: if not _is_null_slice(key[0]): raise AssertionError( "invalid slicing for a 1-ndim categorical") key = key[1] elif len(key) == 1: key = key[0] else: raise AssertionError( "invalid slicing for a 1-ndim categorical") # slicing in Series or Categorical elif isinstance(key, slice): pass # Array of True/False in Series or Categorical else: # There is a bug in numpy, which does not accept a Series as a indexer # https://github.com/pydata/pandas/issues/6168 # https://github.com/numpy/numpy/issues/4240 -> fixed in numpy 1.9 # FIXME: remove when numpy 1.9 is the lowest numpy version pandas accepts... key = np.asarray(key) lindexer = self.levels.get_indexer(rvalue) # FIXME: the following can be removed after https://github.com/pydata/pandas/issues/7820 # is fixed. # float levels do currently return -1 for np.nan, even if np.nan is included in the index # "repair" this here if isnull(rvalue).any() and isnull(self.levels).any(): nan_pos = np.where(com.isnull(self.levels))[0] lindexer[lindexer == -1] = nan_pos self._codes[key] = lindexer