Розглянемо наступний фрейм даних:
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
Наступні команди працюють:
> df.groupby('A').apply(lambda x: (x['C'] - x['D']))
> df.groupby('A').apply(lambda x: (x['C'] - x['D']).mean())
але жодна з наступних робіт:
> 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
Чому? Приклад в документації, схоже, говорить про те, що виклик transform
групи дозволяє виконувати обробку операцій з рядками:
# 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)
Іншими словами, я вважав, що перетворення - це по суті специфічний тип застосувань (той, який не агрегується). Де я помиляюся?
Для довідки, нижче наведена конструкція вихідного фрейму даних:
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
отримує лямбда-функцію, яка передбачає, що кожен x
є елементом в межах group
, а також повертає значення для елемента в групі. Що я пропускаю?
apply
проходить у всьому df, але transform
передає кожен стовпчик окремо як серія. 2) apply
може повернути будь-який вихід фігури (скалярний / Серія / DataFrame / масив / список ...), тоді як transform
повинен повернути послідовність (1D серія / масив / список) тієї ж довжини, що і група. Ось чому ОП apply()
не потрібно transform()
. Це гарне запитання, оскільки доктор не пояснив обох відмінностей чітко. (схоже на відмінність між apply/map/applymap
чи іншими речами ...)
transform
повинна повертати число, рядок або ту ж форму, що і аргумент. якщо це число, то число буде встановлено для всіх елементів у групі, якщо це рядок, воно буде транслюватись у всі рядки групи. У вашому коді функція лямбда повертає стовпець, який неможливо транслювати в групу.