2017-10-18 55 views
3

我有一个熊猫数据帧的数据在一个很宽的形式...例如多指标数据框列:熊猫 - 融化,叠,重塑或基于从列名的多个属性

ID Equipment Function Task exprt_cond1_time exprt_cond2_time exprt_cond1_freq exprt_cond2_freq novce_cond1_time novce_cond2_time novce_cond1_freq novce_cond2_freq 
0 eq_type_1 Fxn_a  task_1 12     24     0.031    0.055    15     31     0.042    0.059 
1 eq_type_1 Fxn_a  task_2 10     22     0.028    0.052    12     29     0.039    0.055 
2 eq_type_1 Fxn_b  task_3 13     25     0.033    0.057    18     34     0.047    0.062 
3 eq_type_1 Fxn_b  task_4 9     19     0.027    0.051    10     28     0.038    0.054 
4 eq_type_2 Fxn_a  task_1 14     27     0.036    0.056    16     32     0.043    0.061 
5 eq_type_2 Fxn_a  task_2 11     26     0.030    0.054    14     30     0.041    0.058 

但我从上面想使用在列标签中的文本,以使新列将其转换为一个更整洁的长格式......例如,从第一个和最后一个行的数据可能看起来更像是这样的:

ID Equipment Function Task Experience Condition Time Freq 
0 eq_type_1 Fxn_a  task_1 expert  cond1  12  0.031 
1 eq_type_1 Fxn_a  task_1 expert  cond2  24  0.055 
2 eq_type_1 Fxn_a  task_1 novice  cond1  15  0.042 
3 eq_type_1 Fxn_a  task_1 novice  cond2  31  0.059 
... 
16 eq_type_2 Fxn_a  task_2 expert  cond1  11  0.030 
17 eq_type_2 Fxn_a  task_2 expert  cond2  26  0.054 
18 eq_type_2 Fxn_a  task_2 novice  cond1  14  0.041 
19 eq_type_2 Fxn_a  task_2 novice  cond2  30  0.058 

我无法弄清楚融化/堆叠/重塑/ MultiIndex或其他的正确组合r翻译功能可以有效地发生这种情况,或者不会让我的代码变得难看,笨拙,几乎不可读。 This questionthis question很接近,并帮助我一些,但它们似乎只是基于标签中的单个属性进行转换。会喜欢来自SO社区的任何帮助或提示!

回答

7

让我们尝试pd.wide_to_long一些列重命名两次使这一切成为可能:

rename_d = {'exprt_cond1_time':'Time_exprt_cond1', 
     'exprt_cond2_time':'Time_exprt_cond2', 
     'exprt_cond1_freq':'Freq_exprt_cond1', 
     'exprt_cond2_freq':'Freq_exprt_cond2', 
     'novce_cond1_time':'Time_novce_cond1', 
     'novce_cond2_time':'Time_novce_cond2', 
     'novce_cond1_freq':'Freq_novce_cond1', 
     'novce_cond2_freq':'Freq_novce_cond2'} 

f = df.rename(columns=rename_d) 

df1 = pd.wide_to_long(df, ['Time_exprt','Freq_exprt','Time_novce','Freq_novce'],i=['Equipment','Function','Task'],j='Condition',sep='_',suffix='.') 

df1 = df1.reset_index() 

df_out = pd.wide_to_long(df1,['Time','Freq'],i=['Equipment','Function','Task','Condition'],j='Experience',sep='_',suffix='').reset_index().drop('ID',axis=1) 

输出:

Equipment Function Task Condition Experience Time Freq 
0 eq_type_1 Fxn_a task_1  cond1 exprt 12 0.031 
1 eq_type_1 Fxn_a task_1  cond1 novce 15 0.042 
2 eq_type_1 Fxn_a task_1  cond2 exprt 24 0.055 
3 eq_type_1 Fxn_a task_1  cond2 novce 31 0.059 
4 eq_type_1 Fxn_a task_2  cond1 exprt 10 0.028 
5 eq_type_1 Fxn_a task_2  cond1 novce 12 0.039 
6 eq_type_1 Fxn_a task_2  cond2 exprt 22 0.052 
7 eq_type_1 Fxn_a task_2  cond2 novce 29 0.055 
8 eq_type_1 Fxn_b task_3  cond1 exprt 13 0.033 
9 eq_type_1 Fxn_b task_3  cond1 novce 18 0.047 
10 eq_type_1 Fxn_b task_3  cond2 exprt 25 0.057 
11 eq_type_1 Fxn_b task_3  cond2 novce 34 0.062 
12 eq_type_1 Fxn_b task_4  cond1 exprt  9 0.027 
13 eq_type_1 Fxn_b task_4  cond1 novce 10 0.038 
14 eq_type_1 Fxn_b task_4  cond2 exprt 19 0.051 
15 eq_type_1 Fxn_b task_4  cond2 novce 28 0.054 
16 eq_type_2 Fxn_a task_1  cond1 exprt 14 0.036 
17 eq_type_2 Fxn_a task_1  cond1 novce 16 0.043 
18 eq_type_2 Fxn_a task_1  cond2 exprt 27 0.056 
19 eq_type_2 Fxn_a task_1  cond2 novce 32 0.061 
20 eq_type_2 Fxn_a task_2  cond1 exprt 11 0.030 
21 eq_type_2 Fxn_a task_2  cond1 novce 14 0.041 
22 eq_type_2 Fxn_a task_2  cond2 exprt 26 0.054 
23 eq_type_2 Fxn_a task_2  cond2 novce 30 0.058 

pd.wide_to_long处理 “同时融化” 的大熊猫。首先,我们需要重命名这些列以使pd.wide_to_long中的存根名称正常工作。

+1

很高兴看到我的好感功能展现出来! :) – Wen

+0

不错!所以干净:) – CJH

2

这里是我的尝试 - 我试图用pd.wide_to_long只有一次:

import re 

cols = ['Equipment', 'Function', 'Task'] 

renamer = lambda c: re.sub(r'([^_]*)_(cond\d+)_(time|freq)', r'\3_\1_\2', c) 

r = pd.wide_to_long(df.drop('ID',1).rename(columns=renamer), 
        stubnames=['time','freq'], i=cols, j='Measures', 
        sep='_',suffix='(?:exprt|novce)_cond\d+') \ 
     .reset_index() 

r[['Experience','Condition']] = r.pop('Measures').str.split('_', expand=True) 

结果:

In [192]: r 
Out[192]: 
    Equipment Function Task time freq Experience Condition 
0 eq_type_1 Fxn_a task_1 12 0.031  exprt  cond1 
1 eq_type_1 Fxn_a task_1 24 0.055  exprt  cond2 
2 eq_type_1 Fxn_a task_1 15 0.042  novce  cond1 
3 eq_type_1 Fxn_a task_1 31 0.059  novce  cond2 
4 eq_type_1 Fxn_a task_2 10 0.028  exprt  cond1 
5 eq_type_1 Fxn_a task_2 22 0.052  exprt  cond2 
6 eq_type_1 Fxn_a task_2 12 0.039  novce  cond1 
7 eq_type_1 Fxn_a task_2 29 0.055  novce  cond2 
8 eq_type_1 Fxn_b task_3 13 0.033  exprt  cond1 
9 eq_type_1 Fxn_b task_3 25 0.057  exprt  cond2 
10 eq_type_1 Fxn_b task_3 18 0.047  novce  cond1 
11 eq_type_1 Fxn_b task_3 34 0.062  novce  cond2 
12 eq_type_1 Fxn_b task_4  9 0.027  exprt  cond1 
13 eq_type_1 Fxn_b task_4 19 0.051  exprt  cond2 
14 eq_type_1 Fxn_b task_4 10 0.038  novce  cond1 
15 eq_type_1 Fxn_b task_4 28 0.054  novce  cond2 
16 eq_type_2 Fxn_a task_1 14 0.036  exprt  cond1 
17 eq_type_2 Fxn_a task_1 27 0.056  exprt  cond2 
18 eq_type_2 Fxn_a task_1 16 0.043  novce  cond1 
19 eq_type_2 Fxn_a task_1 32 0.061  novce  cond2 
20 eq_type_2 Fxn_a task_2 11 0.030  exprt  cond1 
21 eq_type_2 Fxn_a task_2 26 0.054  exprt  cond2 
22 eq_type_2 Fxn_a task_2 14 0.041  novce  cond1 
23 eq_type_2 Fxn_a task_2 30 0.058  novce  cond2 

说明:

In [198]: df.drop('ID',1).rename(columns=renamer) 
Out[198]: 
    Equipment Function Task time_exprt_cond1 time_exprt_cond2 freq_exprt_cond1 freq_exprt_cond2 time_novce_cond1 \ 
0 eq_type_1 Fxn_a task_1    12    24    0.031    0.055    15 
1 eq_type_1 Fxn_a task_2    10    22    0.028    0.052    12 
2 eq_type_1 Fxn_b task_3    13    25    0.033    0.057    18 
3 eq_type_1 Fxn_b task_4     9    19    0.027    0.051    10 
4 eq_type_2 Fxn_a task_1    14    27    0.036    0.056    16 
5 eq_type_2 Fxn_a task_2    11    26    0.030    0.054    14 

    time_novce_cond2 freq_novce_cond1 freq_novce_cond2 
0    31    0.042    0.059 
1    29    0.039    0.055 
2    34    0.047    0.062 
3    28    0.038    0.054 
4    32    0.043    0.061 
5    30    0.041    0.058 

In [199]: pd.wide_to_long(df.drop('ID',1).rename(columns=renamer), 
    ...:     stubnames=['time','freq'], i=cols,j='Measures', 
    ...:     sep='_',suffix='(?:exprt|novce)_cond\d+') \ 
    ...: .reset_index() 
    ...: 
Out[199]: 
    Equipment Function Task  Measures time freq 
0 eq_type_1 Fxn_a task_1 exprt_cond1 12 0.031 
1 eq_type_1 Fxn_a task_1 exprt_cond2 24 0.055 
2 eq_type_1 Fxn_a task_1 novce_cond1 15 0.042 
3 eq_type_1 Fxn_a task_1 novce_cond2 31 0.059 
4 eq_type_1 Fxn_a task_2 exprt_cond1 10 0.028 
5 eq_type_1 Fxn_a task_2 exprt_cond2 22 0.052 
6 eq_type_1 Fxn_a task_2 novce_cond1 12 0.039 
7 eq_type_1 Fxn_a task_2 novce_cond2 29 0.055 
8 eq_type_1 Fxn_b task_3 exprt_cond1 13 0.033 
9 eq_type_1 Fxn_b task_3 exprt_cond2 25 0.057 
10 eq_type_1 Fxn_b task_3 novce_cond1 18 0.047 
11 eq_type_1 Fxn_b task_3 novce_cond2 34 0.062 
12 eq_type_1 Fxn_b task_4 exprt_cond1  9 0.027 
13 eq_type_1 Fxn_b task_4 exprt_cond2 19 0.051 
14 eq_type_1 Fxn_b task_4 novce_cond1 10 0.038 
15 eq_type_1 Fxn_b task_4 novce_cond2 28 0.054 
16 eq_type_2 Fxn_a task_1 exprt_cond1 14 0.036 
17 eq_type_2 Fxn_a task_1 exprt_cond2 27 0.056 
18 eq_type_2 Fxn_a task_1 novce_cond1 16 0.043 
19 eq_type_2 Fxn_a task_1 novce_cond2 32 0.061 
20 eq_type_2 Fxn_a task_2 exprt_cond1 11 0.030 
21 eq_type_2 Fxn_a task_2 exprt_cond2 26 0.054 
22 eq_type_2 Fxn_a task_2 novce_cond1 14 0.041 
23 eq_type_2 Fxn_a task_2 novce_cond2 30 0.058 
+0

哦...这是一个很酷的方法。执行wide_to_long一次,然后拆分列。尼斯,@MaxU! –

+0

@ScottBoston,谢谢! :)感谢您的评论! – MaxU