将多索引转换为行方式多维NumPy数组.

Eri*_*sen 6 python numpy dataframe pandas

假设我有一个类似于MultiIndex文档中的示例的MultiIndex DataFrame.

>>> df 
               0   1   2   3
first second                
bar   one      0   1   2   3
      two      4   5   6   7
baz   one      8   9  10  11
      two     12  13  14  15
foo   one     16  17  18  19
      two     20  21  22  23
qux   one     24  25  26  27
      two     28  29  30  31
Run Code Online (Sandbox Code Playgroud)

我想从这个DataFrame生成一个具有三维结构的NumPy数组

>>> desired_arr
array([[[ 0,  4],
        [ 1,  5],
        [ 2,  6],
        [ 3,  7]],

       [[ 8, 12],
        [ 9, 13],
        [10, 14],
        [11, 15]],

       [[16, 20],
        [17, 21],
        [18, 22],
        [19, 23]],

       [[24, 28],
        [25, 29],
        [26, 30],
        [27, 31]]])
Run Code Online (Sandbox Code Playgroud)

我怎么能这样做

希望很清楚这里发生了什么 - 我实际上是在第一级卸载DataFrame,然后尝试将结果列MultiIndex中的每个顶层转换为它自己的二维数组.

我可以半途而废

>>> df.unstack(1)
         0       1       2       3    
second one two one two one two one two
first                                 
bar      0   4   1   5   2   6   3   7
baz      8  12   9  13  10  14  11  15
foo     16  20  17  21  18  22  19  23
qux     24  28  25  29  26  30  27  31
Run Code Online (Sandbox Code Playgroud)

但后来我很难找到一种很好的方法将每一列变成一个二维数组,然后将它们连接在一起,除了明确地使用循环和列表.

我觉得应该有一些方法让我事先指定我想要的NumPy数组的形状,填充它np.nan然后使用特定的迭代顺序用我的DataFrame填充值,但我没有设法解决这个问题接近.


生成示例DataFrame

iterables = [['bar', 'baz', 'foo', 'qux'], ['one', 'two']]
ind = pd.MultiIndex.from_product(iterables, names=['first', 'second'])
df = pd.DataFrame(np.arange(8*4).reshape((8, 4)), index=ind)
Run Code Online (Sandbox Code Playgroud)

Div*_*kar 7

一些重塑交换魔术 -

df.values.reshape(4,2,-1).swapaxes(1,2)
Run Code Online (Sandbox Code Playgroud)

可归结为 -

m,n = len(df.index.levels[0]), len(df.index.levels[1])
arr = df.values.reshape(m,n,-1).swapaxes(1,2)
Run Code Online (Sandbox Code Playgroud)

基本上将第一轴分成两个长度42创建一个3D数组,然后交换最后两个轴,2即将长度轴推入后面(作为最后一个).

样品输出 -

In [35]: df.values.reshape(4,2,-1).swapaxes(1,2)
Out[35]: 
array([[[ 0,  4],
        [ 1,  5],
        [ 2,  6],
        [ 3,  7]],

       [[ 8, 12],
        [ 9, 13],
        [10, 14],
        [11, 15]],

       [[16, 20],
        [17, 21],
        [18, 22],
        [19, 23]],

       [[24, 28],
        [25, 29],
        [26, 30],
        [27, 31]]])
Run Code Online (Sandbox Code Playgroud)

  • 请注意,只有当您拥有第一个 * 第二个多重索引的完整组合,并且它们按正确的顺序排序时,这才有效,这恰好是示例中的情况。 (2认同)