Сделайте Pandas MultiIndex из продукта iterables?

У меня есть функция утилиты для создания Pandas MultiIndex, когда у меня есть два или более итерационных файла, и я хочу использовать индексный ключ для каждого уникального спаривания значений в этих итерабелях. Похоже на это

import pandas as pd
import itertools

def product_index(values, names=None):
    """Make a MultiIndex from the combinatorial product of the values."""
    iterable = itertools.product(*values)
    idx = pd.MultiIndex.from_tuples(list(iterable), names=names)
    return idx

И может использоваться как:

a = range(3)
b = list("ab")
product_index([a, b])

Чтобы создать

MultiIndex(levels=[[0, 1, 2], [u'a', u'b']],
           labels=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])

Это работает отлично, но это похоже на обычную утилиту, и я удивлен, что мне пришлось ее реализовать самостоятельно. Итак, мой вопрос: что я пропустил/неправильно понял в самой библиотеке Pandas, которая предлагает эту функциональность?

Изменить для добавления: Эта функция была добавлена ​​в Pandas в качестве MultiIndex.from_product для версии 0.13.1.

Ответ 1

Это очень похожая конструкция (но с использованием cartesian_product, которая для больших массивов быстрее, чем itertools.product)

In [2]: from pandas.tools.util import cartesian_product

In [3]: MultiIndex.from_arrays(cartesian_product([range(3),list('ab')]))
Out[3]: 
MultiIndex(levels=[[0, 1, 2], [u'a', u'b']],
           labels=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])

может быть добавлен как метод convience, возможно MultiIndex.from_iterables(...)

PLS открыть проблему (и PR, если хотите)

FYI Я очень редко фактически создаю мультииндекс "вручную", почти всегда проще построить кадр и просто set_index.

In [10]: df = DataFrame(dict(A = np.arange(6), 
                             B = ['foo'] * 3 + ['bar'] * 3, 
                             C = np.ones(6)+np.arange(6)%2)
                       ).set_index(['C','B']).sortlevel()

In [11]: df
Out[11]: 
       A
C B     
1 bar  4
  foo  0
  foo  2
2 bar  3
  bar  5
  foo  1

[6 rows x 1 columns]