Infer names in MultiIndex.from_product if inputs have a name attribute · Issue #27292 · pandas-dev/pandas (original) (raw)

It would be convenient to have from_product infer level names from inputs if at all possible.

Current behavior

a = pd.Series([1, 2, 3], name='a') b = pd.Series(['a', 'b'], name='b')

pd.MultiIndex.from_product([a, b]) MultiIndex(levels=[[1, 2, 3], ['a', 'b']], codes=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])

Current workaround

arrs = [a, b] pd.MultiIndex.from_product(ins, names=[el.name for el in arrs]) MultiIndex(levels=[[1, 2, 3], ['a', 'b']], codes=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]], names=['a', 'b'])

Obviously this would't make sense for lists or arrays being passed in, but in the case of a Series, it would be nice to have the name persisted.


From glancing at the source, it looks like this would be somewhat simple to implement, the naive approach might be something like:

        from pandas.core.arrays.categorical import _factorize_from_iterables
        from pandas.core.reshape.util import cartesian_product

        if not is_list_like(iterables):
            raise TypeError("Input must be a list / sequence of iterables.")
        elif is_iterator(iterables):
            iterables = list(iterables)

        if names is None:
            names = [el.name if hasattr(el, 'name') else None for el in iterables]

        codes, levels = _factorize_from_iterables(iterables)
        codes = cartesian_product(codes)
        return MultiIndex(levels, codes, sortorder=sortorder, names=names)