Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
    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