2017-10-18 84 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