Rozważmy następującą ramkę danych:
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
Działają następujące polecenia:
> df.groupby('A').apply(lambda x: (x['C'] - x['D']))
> df.groupby('A').apply(lambda x: (x['C'] - x['D']).mean())
ale żadna z następujących prac:
> 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
Czemu? Przykład w dokumentacji wydaje się sugerować, że wywołanie transform
grupy pozwala na wykonanie operacji wierszowej:
# 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)
Innymi słowy, myślałem, że transformacja jest w istocie specyficznym typem zastosowania (takim, które nie agreguje). Gdzie się mylę?
Dla porównania poniżej przedstawiono konstrukcję oryginalnej ramki danych powyżej:
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
), transform
otrzymujesz funkcję lambda, która zakłada, że każdy x
jest elementem w group
, a także zwraca wartość na element w grupie. czego mi brakuje?
apply
przechodzi w całym df, ale transform
przekazuje każdą kolumnę indywidualnie jako serię. 2) apply
może zwracać dowolne dane wyjściowe kształtu (skalarne / serie / DataFrame / tablica / lista ...), podczas gdy transform
musi zwracać sekwencję (seria 1D / tablica / lista) o tej samej długości co grupa. Dlatego OP apply()
nie potrzebuje transform()
. To dobre pytanie, ponieważ lekarz nie wyjaśnił jasno obu różnic. (podobne do rozróżnienia między apply/map/applymap
lub innymi rzeczami ...)
transform
musi zwracać liczbę, wiersz lub ten sam kształt co argument. jeśli jest to liczba, liczba zostanie ustawiona na wszystkie elementy w grupie, jeśli jest to wiersz, zostanie nadana do wszystkich wierszy w grupie. W Twoim kodzie funkcja lambda zwraca kolumnę, której nie można rozgłaszać do grupy.