Ответ 1
transform
не так хорошо документирован, но кажется, что способ, которым он работает, заключается в том, что передаваемая функция преобразования - это не вся группа в качестве фреймворка данных, а один столбец одной группы. Я не думаю, что это действительно означало, что вы пытаетесь сделать, и ваше решение с помощью apply
в порядке.
Итак, предположим tips.groupby('smoker').transform(func)
. Будет две группы, назовите их group1 и group2. Преобразование не вызывает func(group1)
и func(group2)
. Вместо этого он вызывает func(group1['total_bill'])
, затем func(group1['tip'])
и т.д., А затем func(group2['total_bill'])
, func(group2['total_bill'])
. Вот пример:
>>> print d
A B C
0 -2 5 4
1 1 -1 2
2 0 2 1
3 -3 1 2
4 5 0 2
>>> def foo(df):
... print ">>>"
... print df
... print "<<<"
... return df
>>> print d.groupby('C').transform(foo)
>>>
2 0
Name: A
<<<
>>>
2 2
Name: B
<<<
>>>
1 1
3 -3
4 5
Name: A
<<<
>>>
1 -1
3 1
4 0
Name: B
# etc.
Вы можете видеть, что foo
сначала вызывается только с столбцом A группы C = 1 исходного кадра данных, затем столбцом B этой группы, затем столбцом A группы C = 2 и т.д..
Это имеет смысл, если вы думаете о том, что такое трансформация. Это означало применение функций преобразования в группах. Но в целом эти функции не будут иметь смысла при применении ко всей группе только к данному столбцу. Например, пример в документах pandas посвящен z-стандартизации с использованием transform
. Если у вас есть DataFrame с столбцами по возрасту и весу, было бы нецелесообразно z-стандартизировать по отношению к среднему значению обеих этих переменных. Это даже не означает ничего, чтобы принять общее значение совокупности чисел, некоторые из которых являются возрастом, а некоторые из них - весами. Вы должны z-стандартизировать возраст по отношению к среднему возрасту и весу по отношению к среднему весу, что означает, что вы хотите преобразовать отдельно для каждого столбца.
Итак, в принципе, здесь вам не нужно использовать преобразование. apply
является подходящей функцией здесь, потому что apply
действительно работает в каждой группе как единый DataFrame, а transform
работает с каждым столбцом каждой группы.