假设我有一个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)
...
如何使用多索引数据框最有效地完成此任务? 谢谢
答案 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)
似乎还是很尴尬,为什么面板仍然被弃用?