|
49 | 49 | from pandas.core import ops
|
50 | 50 | from pandas.core.accessor import PandasDelegate, delegate_names
|
51 | 51 | import pandas.core.algorithms as algorithms
|
52 |
| -from pandas.core.algorithms import _get_data_algo, factorize, take, take_1d, unique1d |
| 52 | +from pandas.core.algorithms import _get_data_algo, factorize, take_1d, unique1d |
53 | 53 | from pandas.core.array_algos.transforms import shift
|
54 |
| -from pandas.core.arrays.base import ExtensionArray, _extension_array_shared_docs |
| 54 | +from pandas.core.arrays._mixins import _T, NDArrayBackedExtensionArray |
| 55 | +from pandas.core.arrays.base import _extension_array_shared_docs |
55 | 56 | from pandas.core.base import NoNewAttributesMixin, PandasObject, _shared_docs
|
56 | 57 | import pandas.core.common as com
|
57 | 58 | from pandas.core.construction import array, extract_array, sanitize_array
|
@@ -199,7 +200,7 @@ def contains(cat, key, container):
|
199 | 200 | return any(loc_ in container for loc_ in loc)
|
200 | 201 |
|
201 | 202 |
|
202 |
| -class Categorical(ExtensionArray, PandasObject): |
| 203 | +class Categorical(NDArrayBackedExtensionArray, PandasObject): |
203 | 204 | """
|
204 | 205 | Represent a categorical variable in classic R / S-plus fashion.
|
205 | 206 |
|
@@ -1238,7 +1239,7 @@ def shift(self, periods, fill_value=None):
|
1238 | 1239 |
|
1239 | 1240 | def _validate_fill_value(self, fill_value):
|
1240 | 1241 | """
|
1241 |
| - Convert a user-facing fill_value to a representation to use with our |
| 1242 | + Convert a user-facing fill_value to a representation to use with our |
1242 | 1243 | underlying ndarray, raising ValueError if this is not possible.
|
1243 | 1244 |
|
1244 | 1245 | Parameters
|
@@ -1768,7 +1769,7 @@ def fillna(self, value=None, method=None, limit=None):
|
1768 | 1769 |
|
1769 | 1770 | return self._constructor(codes, dtype=self.dtype, fastpath=True)
|
1770 | 1771 |
|
1771 |
| - def take(self, indexer, allow_fill: bool = False, fill_value=None): |
| 1772 | + def take(self: _T, indexer, allow_fill: bool = False, fill_value=None) -> _T: |
1772 | 1773 | """
|
1773 | 1774 | Take elements from the Categorical.
|
1774 | 1775 |
|
@@ -1837,16 +1838,23 @@ def take(self, indexer, allow_fill: bool = False, fill_value=None):
|
1837 | 1838 | Categories (2, object): [a, b]
|
1838 | 1839 |
|
1839 | 1840 | Specifying a fill value that's not in ``self.categories``
|
1840 |
| - will raise a ``TypeError``. |
| 1841 | + will raise a ``ValueError``. |
1841 | 1842 | """
|
1842 |
| - indexer = np.asarray(indexer, dtype=np.intp) |
| 1843 | + return NDArrayBackedExtensionArray.take( |
| 1844 | + self, indexer, allow_fill=allow_fill, fill_value=fill_value |
| 1845 | + ) |
1843 | 1846 |
|
1844 |
| - if allow_fill: |
1845 |
| - # convert user-provided `fill_value` to codes |
1846 |
| - fill_value = self._validate_fill_value(fill_value) |
| 1847 | + # ------------------------------------------------------------------ |
| 1848 | + # NDArrayBackedExtensionArray compat |
1847 | 1849 |
|
1848 |
| - codes = take(self._codes, indexer, allow_fill=allow_fill, fill_value=fill_value) |
1849 |
| - return self._constructor(codes, dtype=self.dtype, fastpath=True) |
| 1850 | + @property |
| 1851 | + def _ndarray(self) -> np.ndarray: |
| 1852 | + return self._codes |
| 1853 | + |
| 1854 | + def _from_backing_data(self, arr: np.ndarray) -> "Categorical": |
| 1855 | + return self._constructor(arr, dtype=self.dtype, fastpath=True) |
| 1856 | + |
| 1857 | + # ------------------------------------------------------------------ |
1850 | 1858 |
|
1851 | 1859 | def take_nd(self, indexer, allow_fill: bool = False, fill_value=None):
|
1852 | 1860 | # GH#27745 deprecate alias that other EAs dont have
|
|
0 commit comments