|
13 | 13 | from pandas.errors import PerformanceWarning, UnsortedIndexError
|
14 | 14 | from pandas.util._decorators import Appender, cache_readonly
|
15 | 15 |
|
| 16 | +from pandas.core.dtypes.cast import coerce_indexer_dtype |
16 | 17 | from pandas.core.dtypes.common import (
|
17 | 18 | ensure_int64,
|
18 | 19 | ensure_platform_int,
|
|
40 | 41 | _index_shared_docs,
|
41 | 42 | ensure_index,
|
42 | 43 | )
|
43 |
| -from pandas.core.indexes.frozen import FrozenList, _ensure_frozen |
| 44 | +from pandas.core.indexes.frozen import FrozenList |
44 | 45 | import pandas.core.missing as missing
|
45 | 46 | from pandas.core.sorting import (
|
46 | 47 | get_group_index,
|
@@ -821,17 +822,15 @@ def _set_codes(
|
821 | 822 |
|
822 | 823 | if level is None:
|
823 | 824 | new_codes = FrozenList(
|
824 |
| - _ensure_frozen(level_codes, lev, copy=copy)._shallow_copy() |
| 825 | + _coerce_indexer_frozen(level_codes, lev, copy=copy).view() |
825 | 826 | for lev, level_codes in zip(self._levels, codes)
|
826 | 827 | )
|
827 | 828 | else:
|
828 | 829 | level_numbers = [self._get_level_number(lev) for lev in level]
|
829 | 830 | new_codes = list(self._codes)
|
830 | 831 | for lev_num, level_codes in zip(level_numbers, codes):
|
831 | 832 | lev = self.levels[lev_num]
|
832 |
| - new_codes[lev_num] = _ensure_frozen( |
833 |
| - level_codes, lev, copy=copy |
834 |
| - )._shallow_copy() |
| 833 | + new_codes[lev_num] = _coerce_indexer_frozen(level_codes, lev, copy=copy) |
835 | 834 | new_codes = FrozenList(new_codes)
|
836 | 835 |
|
837 | 836 | if verify_integrity:
|
@@ -1095,7 +1094,8 @@ def _format_native_types(self, na_rep="nan", **kwargs):
|
1095 | 1094 | if mask.any():
|
1096 | 1095 | nan_index = len(level)
|
1097 | 1096 | level = np.append(level, na_rep)
|
1098 |
| - level_codes = level_codes.values() |
| 1097 | + assert not level_codes.flags.writeable # i.e. copy is needed |
| 1098 | + level_codes = level_codes.copy() # make writeable |
1099 | 1099 | level_codes[mask] = nan_index
|
1100 | 1100 | new_levels.append(level)
|
1101 | 1101 | new_codes.append(level_codes)
|
@@ -1998,7 +1998,7 @@ def _assert_take_fillable(
|
1998 | 1998 | if mask.any():
|
1999 | 1999 | masked = []
|
2000 | 2000 | for new_label in taken:
|
2001 |
| - label_values = new_label.values() |
| 2001 | + label_values = new_label |
2002 | 2002 | label_values[mask] = na_value
|
2003 | 2003 | masked.append(np.asarray(label_values))
|
2004 | 2004 | taken = masked
|
@@ -3431,3 +3431,26 @@ def maybe_droplevels(index, key):
|
3431 | 3431 | pass
|
3432 | 3432 |
|
3433 | 3433 | return index
|
| 3434 | + |
| 3435 | + |
| 3436 | +def _coerce_indexer_frozen(array_like, categories, copy: bool = False) -> np.ndarray: |
| 3437 | + """ |
| 3438 | + Coerce the array_like indexer to the smallest integer dtype that can encode all |
| 3439 | + of the given categories. |
| 3440 | +
|
| 3441 | + Parameters |
| 3442 | + ---------- |
| 3443 | + array_like : array-like |
| 3444 | + categories : array-like |
| 3445 | + copy : bool |
| 3446 | +
|
| 3447 | + Returns |
| 3448 | + ------- |
| 3449 | + np.ndarray |
| 3450 | + Non-writeable. |
| 3451 | + """ |
| 3452 | + array_like = coerce_indexer_dtype(array_like, categories) |
| 3453 | + if copy: |
| 3454 | + array_like = array_like.copy() |
| 3455 | + array_like.flags.writeable = False |
| 3456 | + return array_like |
0 commit comments