2017-06-21 7 views
2

groupbyの後にaggを使用すると、columns:functionsの関数が渡された場合、関数は対応する列に適用されます。それにもかかわらず、この構文はtransformでは機能しません。 transformにいくつかの関数を適用する別の方法はありますか?パンダでの変換でいくつかの関数を適用する

のは、例を挙げてみましょう:

import pandas as pd 
df_test = pd.DataFrame([[1,2,3],[1,20,30],[2,30,50],[1,2,33],[2,4,50]],columns = ['a','b','c']) 
Out[1]: 
    a b c 
0 1 2 3 
1 1 20 30 
2 2 30 50 
3 1 2 33 
4 2 4 50 

def my_fct1(series): 
    return series.mean() 

def my_fct2(series): 
    return series.std() 

df_test.groupby('a').agg({'b':my_fct1,'c':my_fct2}) 

Out[2]: 
    c b 
a  
1 16.522712 8 
2 0.000000 17 

前の例では、aggに異なる列に異なる関数を適用する方法を示していますが、我々はそれらを集約せずに列を変換したい場合は、aggはもう使用できません。 。したがって:

a b c 
0 1 2 3 
1 1 22 90 
2 2 30 50 
3 1 24 2970 
4 2 34 2500 

答えて

2

私が思う今(パンダ0.20.2)機能transformdictで実装されていません。機能は同じな長さでSeriesを返す場合

df2 = df_test[['a']].join(df_test.groupby('a').agg({'b':my_fct1,'c':my_fct2}), on='a') 
print (df2) 
    a   c b 
0 1 16.522712 8 
1 1 16.522712 8 
2 2 0.000000 17 
3 1 16.522712 8 
4 2 0.000000 17 

df1 = df_test.set_index('a').groupby('a').agg({'b':np.cumsum,'c':np.cumprod}).reset_index() 
print (df1) 
    a  c b 
0 1  3 2 
1 1 90 22 
2 2 50 30 
3 1 2970 24 
4 2 2500 34 

しかしaggreagte異なる長さがjoinが必要な場合

2

あなたはまだ辞書を使用することができますが、ハックのビットは:

df_test.groupby('a').transform(lambda x: {'b': x.cumsum(), 'c': x.cumprod()}[x.name]) 
Out[427]: 
    b  c 
0 2  3 
1 22 90 
2 30 50 
3 24 2970 
4 34 2500 

もし

df_test.groupby('a').transform({'b':np.cumsum,'c':np.cumprod}) 
Out[3]: 
TypeError: unhashable type: 'dict' 

はどのように我々は、以下の期待される出力と、このようなアクションを実行することができます列Aを維持する必要があります。

df_test.set_index('a')\ 
     .groupby('a')\ 
     .transform(lambda x: {'b': x.cumsum(), 'c': x.cumprod()}[x.name])\ 
     .reset_index() 
Out[429]: 
    a b  c 
0 1 2  3 
1 1 22 90 
2 2 30 50 
3 1 24 2970 
4 2 34 2500 

もう一つの方法は、それ以外の場合は、列名をチェックするために使用することです: - aggなどの関数で列名

df_test.set_index('a')\ 
     .groupby('a')\ 
     .transform(lambda x: x.cumsum() if x.name=='b' else x.cumprod())\ 
     .reset_index() 
関連する問題