A partir deste dataframe
df = pd.DataFrame(
np.arange(3*4).reshape((4, 3)),
index=['a', 'b', 'c', 'd'],
columns=['A', 'B', 'C']
)
print(df)
A B C
a 0 1 2
b 3 4 5
c 6 7 8
d 9 10 11
Quero aplicar duas funções a cada coluna para gerar duas colunas para cada coluna original e obter esta forma, com uma coluna multiíndice aninhada abaixo de cada coluna original:
A B C
x y x y x y
a 10 100 11 101 12 102
b 13 103 14 104 15 105
c 16 106 17 107 18 108
d 19 109 20 110 21 111
porém, algo assim não funciona
df.apply(lambda series:
series.transform([lambda x: x+10, lambda x: x+100])
)
e levantaValueError: If using all scalar values, you must pass an index
Note que não quero usar agg como nesta resposta , pois isso não é uma agregação. Também quero evitar fazer referência a nomes de colunas diretamente.
Você só precisa usar
df.transform()
e dar nomes às suas funções.SOLUÇÃO 1
Uma possível solução, cujos passos são:
Primeiro, ele cria dois novos dataframes: um que adiciona 10 a cada elemento e outro que adiciona 100 a cada elemento.
Em seguida, ele concatena esses dataframes ao longo das colunas usando
pd.concat
withaxis=1
e atribui chaves['x', 'y']
para criar um índice de coluna hierárquico.O método
swaplevel
é aplicado para trocar os níveis da colunaMultiIndex
, seguido pelasort_index
classificação das colunas.SOLUÇÃO 2
Outra solução possível, cujos passos são:
Primeiro, ele cria dois novos dataframes: um onde 10 é adicionado a cada elemento (
df + 10
) e outro onde 100 é adicionado (df + 100
).Esses dois dataframes são combinados em uma
numpy
matriz 3D usandostack
withaxis=2
, resultando em uma matriz onde a terceira dimensão empilha as duas transformações.A matriz é então remodelada em uma matriz bidimensional com o mesmo número de linhas que
df
.Um novo dataframe é criado a partir dessa matriz remodelada, com colunas atribuídas a um índice hierárquico usando
pd.MultiIndex.from_product
.Saída: