|
40 | 40 |
|
41 | 41 | from pandas.core.dtypes.cast import can_hold_element
|
42 | 42 | from pandas.core.dtypes.common import (
|
43 |
| - is_categorical_dtype, |
44 |
| - is_dict_like, |
45 | 43 | is_extension_array_dtype,
|
46 | 44 | is_object_dtype,
|
47 | 45 | is_scalar,
|
|
78 | 76 | )
|
79 | 77 |
|
80 | 78 | from pandas import (
|
81 |
| - Categorical, |
82 | 79 | Index,
|
83 | 80 | Series,
|
84 | 81 | )
|
@@ -882,87 +879,19 @@ def _map_values(self, mapper, na_action=None):
|
882 | 879 | If the function returns a tuple with more than one element
|
883 | 880 | a MultiIndex will be returned.
|
884 | 881 | """
|
885 |
| - # we can fastpath dict/Series to an efficient map |
886 |
| - # as we know that we are not going to have to yield |
887 |
| - # python types |
888 |
| - if is_dict_like(mapper): |
889 |
| - if isinstance(mapper, dict) and hasattr(mapper, "__missing__"): |
890 |
| - # If a dictionary subclass defines a default value method, |
891 |
| - # convert mapper to a lookup function (GH #15999). |
892 |
| - dict_with_default = mapper |
893 |
| - mapper = lambda x: dict_with_default[ |
894 |
| - np.nan if isinstance(x, float) and np.isnan(x) else x |
895 |
| - ] |
896 |
| - else: |
897 |
| - # Dictionary does not have a default. Thus it's safe to |
898 |
| - # convert to an Series for efficiency. |
899 |
| - # we specify the keys here to handle the |
900 |
| - # possibility that they are tuples |
901 |
| - |
902 |
| - # The return value of mapping with an empty mapper is |
903 |
| - # expected to be pd.Series(np.nan, ...). As np.nan is |
904 |
| - # of dtype float64 the return value of this method should |
905 |
| - # be float64 as well |
906 |
| - from pandas import Series |
907 |
| - |
908 |
| - if len(mapper) == 0: |
909 |
| - mapper = Series(mapper, dtype=np.float64) |
910 |
| - else: |
911 |
| - mapper = Series(mapper) |
912 |
| - |
913 |
| - if isinstance(mapper, ABCSeries): |
914 |
| - if na_action not in (None, "ignore"): |
915 |
| - msg = ( |
916 |
| - "na_action must either be 'ignore' or None, " |
917 |
| - f"{na_action} was passed" |
918 |
| - ) |
919 |
| - raise ValueError(msg) |
920 |
| - |
921 |
| - if na_action == "ignore": |
922 |
| - mapper = mapper[mapper.index.notna()] |
923 |
| - |
924 |
| - # Since values were input this means we came from either |
925 |
| - # a dict or a series and mapper should be an index |
926 |
| - if is_categorical_dtype(self.dtype): |
927 |
| - # use the built in categorical series mapper which saves |
928 |
| - # time by mapping the categories instead of all values |
929 |
| - |
930 |
| - cat = cast("Categorical", self._values) |
931 |
| - return cat.map(mapper) |
932 |
| - |
933 |
| - values = self._values |
934 |
| - |
935 |
| - indexer = mapper.index.get_indexer(values) |
936 |
| - new_values = algorithms.take_nd(mapper._values, indexer) |
937 |
| - |
938 |
| - return new_values |
939 |
| - |
940 |
| - # we must convert to python types |
941 |
| - if is_extension_array_dtype(self.dtype) and hasattr(self._values, "map"): |
942 |
| - # GH#23179 some EAs do not have `map` |
943 |
| - values = self._values |
944 |
| - if na_action is not None: |
945 |
| - raise NotImplementedError |
946 |
| - map_f = lambda values, f: values.map(f) |
947 |
| - else: |
948 |
| - values = self._values.astype(object) |
949 |
| - if na_action == "ignore": |
950 |
| - map_f = lambda values, f: lib.map_infer_mask( |
951 |
| - values, f, isna(values).view(np.uint8) |
952 |
| - ) |
953 |
| - elif na_action is None: |
954 |
| - map_f = lib.map_infer |
955 |
| - else: |
956 |
| - msg = ( |
957 |
| - "na_action must either be 'ignore' or None, " |
958 |
| - f"{na_action} was passed" |
959 |
| - ) |
960 |
| - raise ValueError(msg) |
961 |
| - |
962 |
| - # mapper is a function |
963 |
| - new_values = map_f(values, mapper) |
964 |
| - |
965 |
| - return new_values |
| 882 | + arr = extract_array(self, extract_numpy=True, extract_range=True) |
| 883 | + |
| 884 | + if is_extension_array_dtype(arr.dtype): |
| 885 | + # Item "IndexOpsMixin" of "Union[IndexOpsMixin, ExtensionArray, |
| 886 | + # ndarray[Any, Any]]" has no attribute "map" |
| 887 | + return arr.map(mapper, na_action=na_action) # type: ignore[union-attr] |
| 888 | + |
| 889 | + # Argument 1 to "map_array" has incompatible type |
| 890 | + # "Union[IndexOpsMixin, ExtensionArray, ndarray[Any, Any]]"; |
| 891 | + # expected "Union[ExtensionArray, ndarray[Any, Any]]" |
| 892 | + return algorithms.map_array( |
| 893 | + arr, mapper, na_action=na_action # type: ignore[arg-type] |
| 894 | + ) |
966 | 895 |
|
967 | 896 | @final
|
968 | 897 | def value_counts(
|
|
0 commit comments