Skip to content

Infer names in MultiIndex.from_product if inputs have a name attribute #27292

Closed
@user3483203

Description

@user3483203

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)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions