从迭代产品中制作一个Pandas MultiIndex?

时间:2014-01-23 18:37:55

标签: python pandas

当我有两个或更多个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图书馆中错过/误解了哪些提供此功能?

编辑以添加:对于0.13.1版本,此功能added to PandasMultiIndex.from_product

1 个答案:

答案 0 :(得分:11)

这是一个非常相似的结构(但使用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]])

可以作为一种方便的方法添加,也许MultiIndex.from_iterables(...)

请打开一个问题(如果你愿意,可以公关)

仅供参考我很少实际构建一个“手动”的多索引,几乎总是更容易实际构建一个框架而只是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]