将结构化的numpy数组(包含子数组)转换为pandas数据框

时间:2020-03-12 23:10:54

标签: python pandas numpy dataframe numpy-ndarray

问题

作为示例,请考虑以下结构化的numpy数组(包含子数组):

data = [
    (1, (5., 3., 7.), 6),
    (2, (2., 1., 3.), 9),
    (3, (3., 8., 4.), 3),
    (4, (1., 7., 4.), 2),
]
dtype = [('A', '<i8'), ('B', '<f8', (3,)), ('C', '<i8')]
arr = np.array(data, dtype=dtype)

我想将此数组arr转换成如下所示的pandas数据框:

   A  B_1  B_2  B_3  C
0  1  5.0  3.0  7.0  6
1  2  2.0  1.0  3.0  9
2  3  3.0  8.0  4.0  3
3  4  1.0  7.0  4.0  2

到目前为止已尝试

我尝试使用熊猫的方法from_records进行转换:

df = pd.DataFrame.from_records(arr)

但这会引发错误Exception: Data must be 1-dimensional

问题

将这种数据转换为熊猫数据框的好方法是什么?

3 个答案:

答案 0 :(得分:1)

可以通过两次pd.DataFrame调用来压平

df=pd.DataFrame(arr.tolist())
df=df.join(pd.DataFrame(df[1].tolist()).add_prefix('B'))
Out[404]: 
   0                1  2   B0   B1   B2
0  1  [5.0, 3.0, 7.0]  6  5.0  3.0  7.0
1  2  [2.0, 1.0, 3.0]  9  2.0  1.0  3.0
2  3  [3.0, 8.0, 4.0]  3  3.0  8.0  4.0
3  4  [1.0, 7.0, 4.0]  2  1.0  7.0  4.0

答案 1 :(得分:1)

您可以做(假设您知道B列是要扩展的列,如果需要进一步使其自动化,可以遍历dtype -以获取复合类型的列)

df=pd.DataFrame.from_records(map(lambda x: list(x), arr), columns=arr.dtype.names)
df2=pd.DataFrame(df["B"].tolist())
df2.columns=map(lambda x: f"B_{x+1}", df2.columns)

df=pd.concat([df, df2], sort=False, axis=1).drop(columns="B")

输出:

   A  C  B_1  B_2  B_3
0  1  6  5.0  3.0  7.0
1  2  9  2.0  1.0  3.0
2  3  3  3.0  8.0  4.0
3  4  2  1.0  7.0  4.0

答案 2 :(得分:1)

-

看起来像新的In [56]: data = [ ...: (1, (5., 3., 7.), 6), ...: (2, (2., 1., 3.), 9), ...: (3, (3., 8., 4.), 3), ...: (4, (1., 7., 4.), 2), ...: ] ...: dtype = [('A', '<i8'), ('B', '<f8', (3,)), ('C', '<i8')] ...: arr = np.array(data, dtype=dtype) In [57]: arr Out[57]: array([(1, [5., 3., 7.], 6), (2, [2., 1., 3.], 9), (3, [3., 8., 4.], 3), (4, [1., 7., 4.], 2)], dtype=[('A', '<i8'), ('B', '<f8', (3,)), ('C', '<i8')]) 可以处理此dtype:

structure_to_unstructured

然后以通常的方式制作数据框。

In [59]: import numpy.lib.recfunctions as rf                                                   
In [60]: rf.structured_to_unstructured(arr)                                                    
Out[60]: 
array([[1., 5., 3., 7., 6.],
       [2., 2., 1., 3., 9.],
       [3., 3., 8., 4., 3.],
       [4., 1., 7., 4., 2.]])

并在列dtypes中添加

In [63]: pd.DataFrame(_60, columns=['A','B1','B2','B3','C'])                                   
Out[63]: 
     A   B1   B2   B3    C
0  1.0  5.0  3.0  7.0  6.0
1  2.0  2.0  1.0  3.0  9.0
2  3.0  3.0  8.0  4.0  3.0
3  4.0  1.0  7.0  4.0  2.0
相关问题