2016-05-10 25 views
7

zincirleme yöntemiyle gruplandırılmış DataFrame'e sütun ekleyin İlk önce pandalar için yeni olduğumu varsayalım.Python pandas:

DataFrame'de yeni bir sütun oluşturmaya çalışıyorum. Bunu örneğimde gösterildiği gibi yapabilirim. Fakat bunu zincirleme yöntemleriyle yapmak istiyorum, bu yüzden yeni değişkenler atamak zorunda değilim. İlk olarak ben ne elde etmek istediğinizi göstereyim, ben bunun şimdiye kadar yaptıklarından:

In [1]: 
import numpy as np 
from pandas import Series,DataFrame 
import pandas as pd 

In [2]: 
np.random.seed(10) 
df=pd.DataFrame(np.random.randint(1,5,size=(10, 3)), columns=list('ABC')) 
df 

Out [2]: 
A B C 
2 2 1 
4 1 2 
4 1 2 
2 1 2 
2 3 1 
2 1 3 
1 3 1 
4 1 1 
4 4 3 
1 4 3 
In [3]: 
filtered_DF = df[df['B']<2].copy() 
grouped_DF = filtered_DF.groupby('A') 
filtered_DF['C_Share_By_Group'] =filtered_DF.C.div(grouped_DF.C.transform("sum")) 
filtered_DF 

Out [3]: 
A B C C_Share_By_Group 
4 1 2    0.4 
4 1 2    0.4 
2 1 2    0.4 
2 1 3    0.6 
4 1 1    0.2 

Ben yöntemleri zincirleme aynı şeyi başarmak istiyorum. dplyr paketi ile Ar, ben böyle bir şey yapmak mümkün olacaktır: o Ar mutate (dplyr) pandalar içinde assign eşit olduğunu söylüyor pandas documentation yılında

df %>% 
    filter(B<2) %>% 
    group_by(A) %>% 
    mutate('C_Share_By_Group'=C/sum(C)) 

ancak assign bir gruplandırılmış çalışmaz nesne. Ben gruplandırılmış dataframe bir şey atamak çalıştığınızda , bir hata alıyorum: Ben aşağıdaki denedi

"AttributeError: Cannot access callable attribute 'assign' of 'DataFrameGroupBy' objects, try using the 'apply' method"

, ancak yeni sütun eklemek için nasıl bilmiyorum, ya da hatta mümkünse bunu başarmak için zincirleme yöntemlerle:

(df.loc[df.B<2] 
    .groupby('A') 
    #****WHAT GOES HERE?**** apply(something)? 
) 
+0

hoş geldiniz. Python'da dönüşüm kullanabilirsiniz. –

cevap

7

Sen assign deneyebilirsiniz: zorunlu programlamaya işlevsel gelen üzücü dünyaya

print df[df['B']<2].assign(C_Share_By_Group=lambda df: 
         df.C 
         .div(df.groupby('A') 
          .C 
          .transform("sum"))) 

    A B C C_Share_By_Group 
1 4 1 2    0.4 
2 4 1 2    0.4 
3 2 1 2    0.4 
5 2 1 3    0.6 
7 4 1 1    0.2 
+0

Denediğiniz için teşekkür ederiz. Bunun gerçekten aradığım cevap olduğunu sanmıyorum. Metodun zincirinin güzelliğinden biri, bir şeyleri iki kez yapmak zorunda olmamanızdır, çünkü yöntemin çıkışını geçersiniz. Yaklaşımınızda aynı DataFrame'i üç kez filtreliyorsunuz ('df ['B'] <2]'). – LauH

+0

Teşekkürler. Haklısınız, bu yüzden cevap düzenlenmiş ve gereksiz kod kaldırılmıştır. Şimdi kontrol edin. – jezrael

+0

Kodunuzu çalıştırmayı denedim, ancak sonuç koduma eşit değil. C_Share_By_Group 0,250000 0,250000 0,285714 0,428571 0,125000 – LauH

İlgili konular