(indexes, keys, levels=None, names=None)
| 885 | |
| 886 | |
| 887 | def _make_concat_multiindex(indexes, keys, levels=None, names=None) -> MultiIndex: |
| 888 | if (levels is None and isinstance(keys[0], tuple)) or ( |
| 889 | levels is not None and len(levels) > 1 |
| 890 | ): |
| 891 | zipped = list(zip(*keys, strict=True)) |
| 892 | if names is None: |
| 893 | names = [None] * len(zipped) |
| 894 | |
| 895 | if levels is None: |
| 896 | _, levels = factorize_from_iterables(zipped) |
| 897 | else: |
| 898 | levels = [ensure_index(x) for x in levels] |
| 899 | validate_unique_levels(levels) |
| 900 | else: |
| 901 | zipped = [keys] |
| 902 | if names is None: |
| 903 | names = [None] |
| 904 | |
| 905 | if levels is None: |
| 906 | levels = [ensure_index(keys).unique()] |
| 907 | else: |
| 908 | levels = [ensure_index(x) for x in levels] |
| 909 | validate_unique_levels(levels) |
| 910 | |
| 911 | if not all_indexes_same(indexes): |
| 912 | codes_list = [] |
| 913 | |
| 914 | # things are potentially different sizes, so compute the exact codes |
| 915 | # for each level and pass those to MultiIndex.from_arrays |
| 916 | |
| 917 | for hlevel, level in zip(zipped, levels, strict=True): |
| 918 | to_concat = [] |
| 919 | if isinstance(hlevel, Index) and hlevel.equals(level): |
| 920 | lens = [len(idx) for idx in indexes] |
| 921 | codes_list.append(np.repeat(np.arange(len(hlevel)), lens)) |
| 922 | else: |
| 923 | for key, index in zip(hlevel, indexes, strict=True): |
| 924 | # Find matching codes, include matching nan values as equal. |
| 925 | mask = (isna(level) & isna(key)) | (level == key) |
| 926 | if not mask.any(): |
| 927 | raise ValueError(f"Key {key} not in level {level}") |
| 928 | i = np.nonzero(mask)[0][0] |
| 929 | |
| 930 | to_concat.append(np.repeat(i, len(index))) |
| 931 | codes_list.append(np.concatenate(to_concat)) |
| 932 | |
| 933 | concat_index = _concat_indexes(indexes) |
| 934 | |
| 935 | # these go at the end |
| 936 | if isinstance(concat_index, MultiIndex): |
| 937 | levels.extend(concat_index.levels) |
| 938 | codes_list.extend(concat_index.codes) |
| 939 | else: |
| 940 | codes, categories = factorize_from_iterable(concat_index) |
| 941 | levels.append(categories) |
| 942 | codes_list.append(codes) |
| 943 | |
| 944 | if len(names) == len(levels): |
no test coverage detected