从 Numpy 3d 数组有效地创建 Pandas DataFrame

Posted

技术标签:

【中文标题】从 Numpy 3d 数组有效地创建 Pandas DataFrame【英文标题】:Efficiently Creating A Pandas DataFrame From A Numpy 3d array 【发布时间】:2016-07-14 02:37:06 【问题描述】:

假设我们从

import numpy as np
a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])

如何有效地将其制成等效于的 pandas DataFrame

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

【问题讨论】:

我们不应该有'b': [1, 3, 5, 7] 用于该样本吗?另外,您能否添加另一个示例,例如 a = np.random.randint(0,9,(4,3,2)),看看当尺寸具有不同长度时会发生什么? @Divakar 感谢您的精彩评论! 【参考方案1】:

这是一种在 NumPy 上完成大部分处理,然后最终将其作为 DataFrame 输出的方法,就像这样 -

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)

如果您确切地知道列数是2,这样我们会将bc 作为最后两列,a 作为第一列,您可以添加列名称,例如所以-

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

【讨论】:

谢谢!这工作得很好。虽然,我用 x,y,z 替换了 m,n,r。 我找到的将 3d 数组传递给 pandas dataFrame 的最佳解决方案! 由于面板对象刚刚在 pandas v0.25.0 中被删除,这可能应该成为规范的答案。【参考方案2】:

使用Panel

a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b=pd.Panel(rollaxis(a,2)).to_frame()
c=b.set_index(b.index.labels[0]).reset_index()
c.columns=list('abc')

那么a 是:

[[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]]

b 是:

             0  1
major minor      
0     0      1  2
      1      3  4
1     0      5  6
      1      7  8

c 是:

   a  b  c
0  0  1  2
1  0  3  4
2  1  5  6
3  1  7  8

【讨论】:

Panel 已被弃用,请参阅下面@Divakar 的回答

以上是关于从 Numpy 3d 数组有效地创建 Pandas DataFrame的主要内容,如果未能解决你的问题,请参考以下文章

从带有描述的 Numpy nd 数组创建 Pandas DataFrame 的更快方法?

从大型元组/行列表中有效地构建 Pandas DataFrame

从大型元组/行列表中有效地构建 Pandas DataFrame

从具有适当形状的现有迭代中创建3D numpy数组

Pandas:从 2D numpy 数组创建一个数据框,保留它们的顺序

有效地减去不同形状的numpy数组