如何将熊猫MultiIndex DataFrame转换为3D数组

时间:2019-02-10 11:25:31

标签: python arrays pandas numpy

假设我有一个MultiIndex DataFrame:

                                c       o       l       u
major       timestamp                       
ONE         2019-01-22 18:12:00 0.00008 0.00008 0.00008 0.00008 
            2019-01-22 18:13:00 0.00008 0.00008 0.00008 0.00008 
            2019-01-22 18:14:00 0.00008 0.00008 0.00008 0.00008 
            2019-01-22 18:15:00 0.00008 0.00008 0.00008 0.00008 
            2019-01-22 18:16:00 0.00008 0.00008 0.00008 0.00008

TWO         2019-01-22 18:12:00 0.00008 0.00008 0.00008 0.00008 
            2019-01-22 18:13:00 0.00008 0.00008 0.00008 0.00008 
            2019-01-22 18:14:00 0.00008 0.00008 0.00008 0.00008 
            2019-01-22 18:15:00 0.00008 0.00008 0.00008 0.00008 
            2019-01-22 18:16:00 0.00008 0.00008 0.00008 0.00008

鉴于此数据框在主列中有15个类别,4列和一个长度为5的时间索引,因此我想从此DataFrame中生成一个3维的NumPy数组。我想创建一个包含(4,15,5)的形状分别表示(列,类别,时间索引)

应创建一个数组:

array([[[8.e-05, 8.e-05, 8.e-05, 8.e-05, 8.e-05],
        [8.e-05, 8.e-05, 8.e-05, 8.e-05, 8.e-05]],

       [[8.e-05, 8.e-05, 8.e-05, 8.e-05, 8.e-05],
        [8.e-05, 8.e-05, 8.e-05, 8.e-05, 8.e-05]],

       [[8.e-05, 8.e-05, 8.e-05, 8.e-05, 8.e-05],
        [8.e-05, 8.e-05, 8.e-05, 8.e-05, 8.e-05]],

       [[8.e-05, 8.e-05, 8.e-05, 8.e-05, 8.e-05],
        [8.e-05, 8.e-05, 8.e-05, 8.e-05, 8.e-05]]])

过去曾经可以使用pd.Panel做到这一点:

panel = pd.Panel(items=[columns], major_axis=[categories], minor_axis=[time_index], dtype=np.float32)
... 

如何使用多索引数据框最有效地完成此任务? 谢谢

3 个答案:

答案 0 :(得分:5)

由于df.values是一个(15*100, 4)形状的数组,因此您可以调用reshape使其成为一个(15, 100, 4)形状的数组:

arr = df.values.reshape(15, 100, 4)

然后调用transpose重新排列轴的顺序:

arr = arr.transpose(2, 0, 1)

现在arr的形状为(4, 15, 100)


使用reshape/transpose的速度比to_xarray().to_array()快960倍:

In [21]: df = pd.DataFrame(np.random.randint(10, size=(15*100, 4)), index=pd.MultiIndex.from_product([range(15), range(100)], names=['A','B']), columns=list('colu'))

In [22]: %timeit arr = df.values.reshape(15, 100, 4).transpose(2, 0, 1)
3.31 µs ± 23.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [24]: %timeit df.to_xarray().to_array()
3.18 ms ± 24.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [25]: 3180/3.31
Out[25]: 960.7250755287009

答案 1 :(得分:3)

如何使用xarray

res = df.to_xarray().to_array()

结果是形状为(4、15、5)的数组

事实上,现在的文档recommend this可以替代熊猫Panel。请注意,您必须安装xarray软件包。

答案 2 :(得分:1)

如果短轴长度不同,则可以尝试以下方法:

df.unstack().ffill().bfill().stack().values.reshape(*df.index.levshape,-1)

似乎还是很尴尬,为什么面板仍然被弃用?