2016-05-10 6 views
7

Prima di dire che sono nuovo per i panda.Panda Python: aggiungi la colonna al DataFrame raggruppato con il metodo di concatenamento

Sto cercando di creare una nuova colonna in un DataFrame. Sono in grado di farlo come mostrato nel mio esempio. Ma voglio farlo concatenando i metodi, quindi non devo assegnare nuove variabili. Permettetemi innanzitutto di mostrare quello che voglio raggiungere, e quello che ho fatto finora:

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 

voglio ottenere la stessa cosa concatenando metodi. In R con dplyr pacchetto, sarei in grado di fare qualcosa di simile:

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

Nel pandas documentation si dice che mutate in R (dplyr) è pari a assign in panda, ma assign non funziona su un raggruppate oggetto. Quando provo ad assegnare qualcosa a dataframe raggruppati, ottengo un errore:

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

ho provato quanto segue, ma non sanno come aggiungere la nuova colonna, o se è persino possibile per raggiungere questo obiettivo con metodi concatenamento:

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

Benvenuti nel mondo triste da funzionale alla programmazione imperativa. Puoi usare trasformare in Python –

risposta

7

Si può provare assign:

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

Grazie per aver provato. Non penso che questa sia davvero la risposta che stavo cercando. Una delle bellezze del concatenamento dei metodi è che non devi fare le cose due volte, mentre stai passando l'output del metodo. Nel tuo approccio stai filtrando lo stesso DataFrame per tre volte ('df ['B'] <2]'). – LauH

+0

Grazie. Hai ragione, quindi la risposta è stata modificata e il codice non necessario è stato rimosso. Si prega di controllare ora. – jezrael

+0

Ho provato a eseguire il codice, ma il risultato non è uguale al mio codice. C_Share_By_Group 0,250000 0,250000 0,285714 0,428571 0,125000 – LauH

Problemi correlati