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

Bra*_*rad 8 python arrays numpy pandas

假设我有一个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
Run Code Online (Sandbox Code Playgroud)

我希望从这个DataFrame生成一个带有3维的NumPy数组,假设数据框在主列中有15个类别,4列和一个长度为5的时间索引.我想创建一个形状为(的numpy数组)4,15,5)分别表示(columns,categories,time_index).

应该创建一个数组:

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]]])
Run Code Online (Sandbox Code Playgroud)

曾经可以使用pd.Panel执行此操作:

panel = pd.Panel(items=[columns], major_axis=[categories], minor_axis=[time_index], dtype=np.float32)
... 
Run Code Online (Sandbox Code Playgroud)

如何通过多索引数据框最有效地实现这一目标? 谢谢

unu*_*tbu 8

既然df.values是一个(15*100, 4)数组,你可以调用reshape它来形成一个(15, 100, 4)数组:

arr = df.values.reshape(15, 100, 4)
Run Code Online (Sandbox Code Playgroud)

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

arr = arr.transpose(2, 0, 1)
Run Code Online (Sandbox Code Playgroud)

现在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
Run Code Online (Sandbox Code Playgroud)


Jos*_*der 5

怎么样使用xarray

res = df.to_xarray().to_array()
Run Code Online (Sandbox Code Playgroud)

结果是一个形状数组(4、15、5)

实际上,文档现在建议将其作为熊猫的替代品Panel。请注意,您必须已xarray安装该软件包。

  • 请注意,在某些情况下,对于大型数据帧,此方法可能会非常慢。我用包含数百万个单元格的数据框尝试了这一点。根据列中的变量和行中的变量,在一种情况下时间为几秒,但在另一种情况下我在大约 20 分钟后停止执行。 (2认同)