Considera il seguente frame di dati:
A B C D
0 foo one 0.162003 0.087469
1 bar one -1.156319 -1.526272
2 foo two 0.833892 -1.666304
3 bar three -2.026673 -0.322057
4 foo two 0.411452 -0.954371
5 bar two 0.765878 -0.095968
6 foo one -0.654890 0.678091
7 foo three -1.789842 -1.130922
I seguenti comandi funzionano:
> df.groupby('A').apply(lambda x: (x['C'] - x['D']))
> df.groupby('A').apply(lambda x: (x['C'] - x['D']).mean())
ma nessuno dei seguenti lavori:
> df.groupby('A').transform(lambda x: (x['C'] - x['D']))
ValueError: could not broadcast input array from shape (5) into shape (5,3)
> df.groupby('A').transform(lambda x: (x['C'] - x['D']).mean())
TypeError: cannot concatenate a non-NDFrame object
Perché? L'esempio sulla documentazione sembra suggerire che la chiamata transforma un gruppo consente di eseguire l'elaborazione delle operazioni per riga:
# Note that the following suggests row-wise operation (x.mean is the column mean)
zscore = lambda x: (x - x.mean()) / x.std()
transformed = ts.groupby(key).transform(zscore)
In altre parole, ho pensato che la trasformazione sia essenzialmente un tipo specifico di applicazione (quello che non si aggrega). Dove sbaglio?
Per riferimento, di seguito è riportata la costruzione del frame di dati originale sopra:
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
'foo', 'bar', 'foo', 'foo'],
'B' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'C' : randn(8), 'D' : randn(8)})
zscore), transformriceve una funzione lambda che presuppone che ciascuno di essi xsia un elemento all'interno di groupe restituisca anche un valore per elemento nel gruppo. Cosa mi sto perdendo?
applypassa nell'intero df, ma transformpassa ciascuna colonna singolarmente come una serie. 2) applypuò restituire qualsiasi output di forma (scalare / Serie / DataFrame / array / elenco ...), mentre transformdeve restituire una sequenza (Serie 1D / array / elenco) della stessa lunghezza del gruppo. Ecco perché apply()non è necessario il PO transform(). Questa è una buona domanda poiché il documento non ha spiegato chiaramente entrambe le differenze. (simile alla distinzione tra apply/map/applymap, o altre cose ...)

transformdeve restituire un numero, una riga o la stessa forma dell'argomento. se è un numero, il numero verrà impostato su tutti gli elementi del gruppo, se è una riga, verrà trasmesso a tutte le righe del gruppo. Nel tuo codice, la funzione lambda restituisce una colonna che non può essere trasmessa al gruppo.