从一个numpy 3D数组创建整洁的pandas dataframe

3
我有一个numpy 3D数组: mat.data['Sylvain_2015'].shape = (180, 12, 15) 这个数组中每个参与者(第一维:180),每个肌肉(第二维:12)和每个条件(第三维:15)都有一个变量(肌肉激活度)。
我想把这个数组转换成下面的pandas数据框:
       muscle  participant    activation  test
0           1            1    100.000000     1
1           1            1     69.322225     2
2           1            1     84.917656     3
3           1            1     80.983069     4
4           1            1     65.163384     5
5           1            1     30.528706     6

有没有比使用三个for循环更高效的方法:

participants, muscles, tests, relative_mvc = ([] for i in range(4))

    for iparticipant in range(mat.data[idataset].shape[0]):
            for imuscle in range(mat.data[idataset].shape[1]):
                max_mvc = np.nanmax(mat.data[idataset][iparticipant, imuscle, :])
                for itest in range(mat.data[idataset].shape[2]):
                    participants.append(iparticipant+1)
                    datasets.append(idataset)
                    muscles.append(imuscle+1)
                    tests.append(itest+1)
                    # normalize mvc (relative to max)
                    activation.append(mat.data[idataset][iparticipant, imuscle, itest]*100/max_mvc)

df = pd.DataFrame({
    'participant': participants,
    'dataset': datasets,
    'muscle': muscles,
    'test': tests,
    'relative_mvc': relative_mvc,
}).dropna()

这是两个参与者的3D数组示例(使用这篇有用的帖子创建).
# Array shape: (2, 12, 15)
0.13    0.09    0.11    0.11    0.09    0.04    0.03    0.06    0.11    0.09    0.03    0.10    0.01    0.03    0.08   
0.21    0.36    0.34    0.18    0.25    0.23    0.11    0.05    0.27    0.27    0.13    0.26    0.04    0.02    0.34   
0.16    0.09    0.41    0.28    0.20    0.10    0.16    0.04    0.15    0.25    0.04    0.18    0.02    0.09    0.24   
nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan    
0.09    0.09    0.10    0.09    0.08    0.05    0.01    0.02    0.08    0.07    0.08    0.08    0.01    0.02    0.09   
0.17    0.39    0.33    0.21    0.17    0.29    0.06    0.01    0.21    0.25    0.27    0.22    0.03    0.01    0.31   
0.01    0.01    0.01    0.03    0.01    0.01    0.03    0.06    0.01    0.01    0.04    0.01    0.03    0.06    0.01   
0.06    0.01    0.07    0.07    0.07    0.03    0.06    0.12    0.09    0.08    0.04    0.04    0.04    0.03    0.10   
0.01    0.03    0.02    0.01    0.01    0.11    0.10    0.01    0.01    0.01    0.09    0.01    0.04    0.01    0.02   
0.10    0.10    0.14    0.11    0.08    0.03    0.01    0.02    0.05    0.06    0.01    0.09    0.01    0.01    0.10   
0.05    0.03    0.06    0.08    0.08    0.01    0.03    0.02    0.03    0.04    0.02    0.07    0.00    0.02    0.06   
0.04    0.05    0.03    0.02    0.08    0.03    0.02    0.02    0.06    0.05    0.02    0.06    0.03    0.01    0.02   
# New slice
0.21    0.08    0.15    0.11    0.15    0.05    0.01    0.01    0.06    0.04    0.02    0.13    0.02    0.02    0.16   
0.26    0.14    0.18    0.12    0.22    0.10    0.10    0.07    0.12    0.17    0.09    0.18    0.03    0.02    0.13   
0.10    0.13    0.13    0.05    0.08    0.08    0.08    0.03    0.03    0.06    0.10    0.06    0.05    0.02    0.05   
nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan     nan    
0.11    0.08    0.10    0.07    0.10    0.05    0.02    0.02    0.05    0.03    0.03    0.10    0.05    0.04    0.10   
0.13    0.20    0.18    0.12    0.12    0.17    0.03    0.01    0.12    0.10    0.12    0.15    0.09    0.04    0.16   
0.02    0.01    0.01    0.06    0.03    0.01    0.03    0.06    0.02    0.01    0.04    0.04    0.04    0.05    0.04   
0.02    0.02    0.04    0.03    0.05    0.04    0.07    0.03    0.04    0.01    0.02    0.06    0.03    0.03    0.03   
0.02    0.03    0.02    0.02    0.02    0.07    0.04    0.02    0.01    0.01    0.04    0.02    0.03    0.02    0.02   
0.07    0.11    0.14    0.03    0.04    0.08    0.01    0.01    0.10    0.11    0.01    0.02    0.01    0.01    0.02   
0.03    0.02    0.03    0.05    0.04    0.01    0.01    0.02    0.01    0.03    0.01    0.04    0.01    0.01    0.03   
0.04    0.05    0.03    0.03    0.04    0.06    0.02    0.01    0.01    0.03    0.05    0.03    0.03    0.02    0.02   
# New slice

有趣的问题。数据会有所帮助。您能将您的3D numpy数组导出为文本样本吗?请参见此处 - Parfait
谢谢。已添加您的建议提供的数据。 - Romain Martinez
1个回答

2

我可以想到几种方法。以下是一种不使用循环的方法,首先创建一个面板(Panel),然后转换为数据帧(dataframe)。

# normalize values first
max_values = np.nanmax(mat.data[idataset], axis=2)
values = mat.data[idataset]*100/max_values.reshape(max_values.shape +(1,))

# get sizes
iparticipant, imuscle, itest = mat.data[idataset].shape

# set axes labels
items = np.arange(1, 1+iparticipant)
major_axis = np.arange(1, imuscle+1)
minor_axis = np.arange(1, itest + 1)

# make a panel (3-d dataframe)
panel = pd.Panel(values, items=iparticipant, major_axis=major_axis, minor_axis=minor_axis)

# covert to dataframe and fix column labels
df = panel.to_frame().stack().reset_index()
df.columns = ['muscle', 'test', 'participant', 'relative_mvc']
df['dataset'] = idataset

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接