2017-08-22 7 views
3

私はこの移調と集約データフレーム

name tag time val 
0 ABC A  1 10 
0 ABC A  1 12 
1 ABC B  1 12 
1 ABC B  1 14 
2 ABC A  2 11 
3 ABC C  2 12 
4 DEF B  3 10 
5 DEF C  3 9 
6 GHI A  4 14 
7 GHI B  4 12 
8 GHI C  5 10 

各行のようなデータフレームはタイムスタンプであり、その行の名前とタグの間の値を示しています。

私がしたいことは、このように、各行がそれぞれのタイムスタンプで、各タグからの平均値を示したデータフレームである:

name time  A  B  C 
0 ABC  1 11.0 13.0 NaN 
1 ABC  2 11.0 NaN 12.0 
2 DEF  3 NaN 10.0 9.0 
3 GHI  4 14.0 12.0 NaN 
4 GHI  5 NaN NaN 10.0 

私はnametimeによってグループ化し、転置シリーズを返すことによって成功し、これを達成することができます毎回:

def transpose_df(observation_df): 
    ser = pd.Series() 
    for tag in tags: 
    ser[tag] = observation_df[observation_df['tag'] == tag]['val'].mean() 
    return ser 


tdf = df.groupby(['name', 'time']).apply(transpose_df).reset_index() 

これは遅いです。組み込みのトランスポーズ/リシェイプツールを使ってよりスマートな方法が必要なような気がしますが、わかりません。誰ももっと良い選択肢を提案することができますか?

答えて

5

オプション1

使用pivot_table

df.pivot_table(values='val',index=['name','time'],columns='tag',aggfunc='mean').reset_index() 

出力:

tag name time  A  B  C 
0 ABC  1 11.0 13.0 NaN 
1 ABC  2 11.0 NaN 12.0 
2 DEF  3 NaN 10.0 9.0 
3 GHI  4 14.0 12.0 NaN 
4 GHI  5 NaN NaN 10.0 

オプション2:

groupby使用してunstack

df.groupby(['name','time','tag']).agg('mean')['val'].unstack().reset_index() 

出力:

tag name time  A  B  C 
0 ABC  1 11.0 13.0 NaN 
1 ABC  2 11.0 NaN 12.0 
2 DEF  3 NaN 10.0 9.0 
3 GHI  4 14.0 12.0 NaN 
4 GHI  5 NaN NaN 10.0 

オプション3

使用​​とmeanunstack

df.set_index(['name','time','tag']).mean(level=[0,1,2])['val'].unstack().reset_index() 

出力:

tag name time  A  B  C 
0 ABC  1 11.0 13.0 NaN 
1 ABC  2 11.0 NaN 12.0 
2 DEF  3 NaN 10.0 9.0 
3 GHI  4 14.0 12.0 NaN 
4 GHI  5 NaN NaN 10.0 
+0

はい、本当にありがとうございました - ありがとうございました!すべての答えは素晴らしかったですが、いくつかのオプションを指定したので、私はあなたを受け入れました。 – DaveBensonPhillips

6
In [175]: df.pivot_table(index=['name','time'], columns='tag', values='val').reset_index() 
Out[175]: 
tag name time  A  B  C 
0 ABC  1 11.0 13.0 NaN 
1 ABC  2 11.0 NaN 12.0 
2 DEF  3 NaN 10.0 9.0 
3 GHI  4 14.0 12.0 NaN 
4 GHI  5 NaN NaN 10.0 
4

グループ化してからアンスタックすることもできます(ピボットテーブルに相当)。ところで

>>> df.groupby(['name', 'time', 'tag'])['val'].mean().unstack('tag').reset_index() 
tag name time A B C 
0 ABC  1 11 13 NaN 
1 ABC  2 11 NaN 12 
2 DEF  3 NaN 10 9 
3 GHI  4 14 12 NaN 
4 GHI  5 NaN NaN 10 

transformあなたは、例えば、元のデータフレームの形状を維持したいときのためにあります

>>> df.assign(tag_mean=df.groupby(['name', 'time', 'tag'])['val'].transform(np.mean)) 
    name tag time val tag_mean 
0 ABC A  1 10  11 
0 ABC A  1 12  11 
1 ABC B  1 12  13 
1 ABC B  1 14  13 
2 ABC A  2 11  11 
3 ABC C  2 12  12 
4 DEF B  3 10  10 
5 DEF C  3 9   9 
6 GHI A  4 14  14 
7 GHI B  4 12  12 
8 GHI C  5 10  10 
関連する問題