Pivot Pandas数据帧与数字和文本字段的混合

时间:2015-12-12 18:07:44

标签: python pandas

我有这个数据框

Athlete   Race  Distance  Rank  Time
M.Smith    A    400m.     1     48.57
A.Moyet    A    400m.     2     49.00
C.Marconi  B    800m      5     104.12
M.Smith    B    800m.     3     102.66

并希望将其变为

Athlete  Race#1  Distance#1  Rank#1  Time#1  Race#2  Distance#2  Rank#2  Time#2
M.Smith   A      400m        1        48.57   B       800m        3      102.66
A.Moyet   A      400m        2        49.00   NaN     NaN         NaN    NaN
C.Marconi B      800m        5        104.12  NaN     NaN         NaN    NaN

感谢您的回答!

1 个答案:

答案 0 :(得分:1)

诀窍是为每一行分配一个比赛号码(例如1或2),具体取决于它是否应该与比赛#1或比赛#2相关联:

df['race'] = df.groupby('Athlete').cumcount()+1
#      Athlete Distance Race  Rank    Time  race
# 0    M.Smith     400m    A     1   48.57     1
# 1    A.Moyet     400m    A     2   49.00     1
# 2  C.Marconi     800m    B     5  104.12     1
# 3    M.Smith     800m    B     3  102.66     2

然后,所需的DataFrame可以表示为set_index/unstack操作的结果:

result = df.set_index(['Athlete', 'race']).unstack('race')
#           Distance       Race      Rank        Time        
# race             1     2    1    2    1   2       1       2
# Athlete                                                    
# A.Moyet       400m   NaN    A  NaN    2 NaN   49.00     NaN
# C.Marconi     800m   NaN    B  NaN    5 NaN  104.12     NaN
# M.Smith       400m  800m    A    B    1   3   48.57  102.66

set_indexAthleterace列移动到索引中。 unstack操作会将race索引级别移动到列级别。

这一点,以及稍微修改以获得所需格式的列:

import pandas as pd
df = pd.DataFrame({'Athlete': ['M.Smith', 'A.Moyet', 'C.Marconi', 'M.Smith'],
                   'Distance': ['400m', '400m', '800m', '800m'],
                   'Race': ['A', 'A', 'B', 'B'],
                   'Rank': [1, 2, 5, 3],
                   'Time': [48.57, 49.0, 104.12, 102.66]})

df['race'] = df.groupby('Athlete').cumcount()+1
result = df.set_index(['Athlete', 'race']).unstack('race')
result = result.sortlevel('race', axis='columns')
result.columns = ['{}#{}'.format(col, n) for col, n in result.columns]
print(result)

产量

          Distance#1 Race#1  Rank#1  Time#1 Distance#2 Race#2  Rank#2  Time#2
Athlete                                                                      
A.Moyet         400m      A       2   49.00        NaN    NaN     NaN     NaN
C.Marconi       800m      B       5  104.12        NaN    NaN     NaN     NaN
M.Smith         400m      A       1   48.57       800m      B       3  102.66