Considere o seguinte quadro de dados:
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
Os seguintes comandos funcionam:
> df.groupby('A').apply(lambda x: (x['C'] - x['D']))
> df.groupby('A').apply(lambda x: (x['C'] - x['D']).mean())
mas nenhum dos seguintes trabalhos:
> 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ê? O exemplo na documentação parece sugerir que a chamada transform
a um grupo permite executar o processamento de operações em linhas:
# 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)
Em outras palavras, eu pensei que transformar é essencialmente um tipo específico de aplicação (aquele que não agrega). Onde eu estou errado?
Para referência, abaixo está a construção do quadro de dados original acima:
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
recebe uma função lambda que assume que cada x
um é um item dentro do group
e também retorna um valor por item no grupo. o que estou perdendo?
apply
passa em todo o df, mas transform
passa cada coluna individualmente como uma série. 2) apply
pode retornar qualquer saída de forma (escalar / Série / DataFrame / matriz / lista ...), enquanto transform
deve retornar uma sequência (1D Série / matriz / lista) do mesmo comprimento que o grupo. É por isso que o OP apply()
não precisa transform()
. Essa é uma boa pergunta, pois o documento não explicou claramente as duas diferenças. (semelhante à distinção entre apply/map/applymap
, ou outras coisas ...)
transform
deve retornar um número, uma linha ou a mesma forma que o argumento. se for um número, o número será definido para todos os elementos do grupo; se for uma linha, será transmitido para todas as linhas do grupo. No seu código, a função lambda retorna uma coluna que não pode ser transmitida para o grupo.