Considere el siguiente marco de datos:
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
Los siguientes comandos funcionan:
> df.groupby('A').apply(lambda x: (x['C'] - x['D']))
> df.groupby('A').apply(lambda x: (x['C'] - x['D']).mean())
pero ninguno de los siguientes trabajos:
> 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
¿Por qué? El ejemplo en la documentación parece sugerir que llamar transforma un grupo le permite a uno realizar el procesamiento de operaciones en filas:
# 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)
En otras palabras, pensé que transform es esencialmente un tipo específico de aplicación (el que no se agrega). Donde me equivoco
Como referencia, a continuación se muestra la construcción del marco de datos original anterior:
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), transformrecibe una función lambda que supone que cada uno xes un elemento dentro del group, y también devuelve un valor por elemento en el grupo. ¿Qué me estoy perdiendo?
applypasa todo el df, pero transformpasa cada columna individualmente como una Serie. 2) applypuede devolver cualquier salida de forma (escalar / Serie / Marco de datos / matriz / lista ...), mientras que transformdebe devolver una secuencia (Serie 1D / matriz / lista) de la misma longitud que el grupo. Es por eso que el OP apply()no necesita transform(). Esta es una buena pregunta ya que el documento no explicó ambas diferencias claramente. (similar a la distinción apply/map/applymapu otras cosas ...)

transformdebe devolver un número, una fila o la misma forma que el argumento. si es un número, el número se establecerá en todos los elementos del grupo, si es una fila, se transmitirá a todas las filas del grupo. En su código, la función lambda devuelve una columna que no se puede transmitir al grupo.