从Numpy 3d阵列高效创建数据帧
假设我们从从Numpy 3d阵列高效创建数据帧,numpy,pandas,multidimensional-array,vectorization,Numpy,Pandas,Multidimensional Array,Vectorization,假设我们从 import numpy as np a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) 如何有效地将其制作成与 import pandas as pd >>> pd.DataFrame({'a': [0, 0, 1, 1], 'b': [1, 3, 5, 7], 'c': [2, 4, 6, 8]}) a b c 0 0 1 2 1 0 3 4 2 1 5 6 3 1 7 8
import numpy as np
a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
如何有效地将其制作成与
import pandas as pd
>>> pd.DataFrame({'a': [0, 0, 1, 1], 'b': [1, 3, 5, 7], 'c': [2, 4, 6, 8]})
a b c
0 0 1 2
1 0 3 4
2 1 5 6
3 1 7 8
其思想是让a
列在原始数组的第一维中具有索引,其余列是原始数组的后两维中的二维数组的垂直串联
(使用循环很容易做到这一点;问题是如何在没有循环的情况下做到这一点。)
较长示例 使用@Divakar的优秀建议:
>>> np.random.randint(0,9,(4,3,2))
array([[[0, 6],
[6, 4],
[3, 4]],
[[5, 1],
[1, 3],
[6, 4]],
[[8, 0],
[2, 3],
[3, 1]],
[[2, 2],
[0, 0],
[6, 3]]])
应制作成以下形状:
>>> pd.DataFrame({
'a': [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3],
'b': [0, 6, 3, 5, 1, 6, 8, 2, 3, 2, 0, 6],
'c': [6, 4, 4, 1, 3, 4, 0, 3, 1, 2, 0, 3]})
a b c
0 0 0 6
1 0 6 4
2 0 3 4
3 1 5 1
4 1 1 3
5 1 6 4
6 2 8 0
7 2 2 3
8 2 3 1
9 3 2 2
10 3 0 0
11 3 6 3
使用:
那么a
是:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
0 1
major minor
0 0 1 2
1 3 4
1 0 5 6
1 7 8
a b c
0 0 1 2
1 0 3 4
2 1 5 6
3 1 7 8
b
是:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
0 1
major minor
0 0 1 2
1 3 4
1 0 5 6
1 7 8
a b c
0 0 1 2
1 0 3 4
2 1 5 6
3 1 7 8
而c
是:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
0 1
major minor
0 0 1 2
1 3 4
1 0 5 6
1 7 8
a b c
0 0 1 2
1 0 3 4
2 1 5 6
3 1 7 8
这里有一种方法,在最终将NumPy作为数据帧输出之前,它在NumPy上执行大部分处理,如下所示-
m,n,r = a.shape
out_arr = np.column_stack((np.repeat(np.arange(m),n),a.reshape(m*n,-1)))
out_df = pd.DataFrame(out_arr)
out_df = pd.DataFrame(out_arr,columns=['a', 'b', 'c'])
如果您确切地知道列的数量是2
,那么我们将b
和c
作为最后两列,a
作为第一列,您可以这样添加列名-
m,n,r = a.shape
out_arr = np.column_stack((np.repeat(np.arange(m),n),a.reshape(m*n,-1)))
out_df = pd.DataFrame(out_arr)
out_df = pd.DataFrame(out_arr,columns=['a', 'b', 'c'])
样本运行-
>>> a
array([[[2, 0],
[1, 7],
[3, 8]],
[[5, 0],
[0, 7],
[8, 0]],
[[2, 5],
[8, 2],
[1, 2]],
[[5, 3],
[1, 6],
[3, 2]]])
>>> out_df
a b c
0 0 2 0
1 0 1 7
2 0 3 8
3 1 5 0
4 1 0 7
5 1 8 0
6 2 2 5
7 2 8 2
8 2 1 2
9 3 5 3
10 3 1 6
11 3 3 2
我们不应该为该示例设置
'b':[1,3,5,7]
?另外,您是否可以添加另一个示例,例如a=np.random.randint(0,9,(4,3,2))
,看看维度长度不同时会出现什么情况?@Divakar感谢您的精彩评论!谢谢这很有效。尽管如此,我还是用x、y、z替换了m、n、r。这是我找到的将3d阵列传递到熊猫数据帧的最佳解决方案!!由于pandas v0.25.0中刚刚删除了Panel对象,这可能会成为标准答案。Panel
已被弃用,请参见@Divakar下面的答案