Eu esperava que sua sintaxe funcionasse também. O problema surge porque quando você cria novas colunas com a sintaxe da lista de colunas ( df[[new1, new2]] = ...
), o pandas requer que o lado direito seja um DataFrame (note que na verdade não importa se as colunas do DataFrame têm os mesmos nomes que as colunas você está criando).
Sua sintaxe funciona bem para atribuir valores escalares a colunas existentes , e o pandas também fica feliz em atribuir valores escalares a uma nova coluna usando a sintaxe de coluna única ( df[new1] = ...
). Portanto, a solução é converter isso em várias atribuições de coluna única ou criar um DataFrame adequado para o lado direito.
Aqui estão algumas abordagens que irá trabalhar:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'col_1': [0, 1, 2, 3],
'col_2': [4, 5, 6, 7]
})
Em seguida, um dos seguintes:
1) Três atribuições em uma, usando a descompactação de lista:
df['column_new_1'], df['column_new_2'], df['column_new_3'] = [np.nan, 'dogs', 3]
2) DataFrame
expande convenientemente uma única linha para corresponder ao índice, para que você possa fazer o seguinte:
df[['column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame([[np.nan, 'dogs', 3]], index=df.index)
3) Faça um quadro de dados temporário com novas colunas, depois combine com o quadro de dados original:
df = pd.concat(
[
df,
pd.DataFrame(
[[np.nan, 'dogs', 3]],
index=df.index,
columns=['column_new_1', 'column_new_2', 'column_new_3']
)
], axis=1
)
4) Semelhante ao anterior, mas usando em join
vez de concat
(pode ser menos eficiente):
df = df.join(pd.DataFrame(
[[np.nan, 'dogs', 3]],
index=df.index,
columns=['column_new_1', 'column_new_2', 'column_new_3']
))
5) Usar um dict é uma maneira mais "natural" de criar o novo quadro de dados do que os dois anteriores, mas as novas colunas serão classificadas em ordem alfabética (pelo menos antes do Python 3.6 ou 3.7 ):
df = df.join(pd.DataFrame(
{
'column_new_1': np.nan,
'column_new_2': 'dogs',
'column_new_3': 3
}, index=df.index
))
6) Use .assign()
com vários argumentos de coluna.
Gosto muito dessa variante da resposta de @zero, mas, como a anterior, as novas colunas sempre serão classificadas em ordem alfabética, pelo menos com as primeiras versões do Python:
df = df.assign(column_new_1=np.nan, column_new_2='dogs', column_new_3=3)
new_cols = ['column_new_1', 'column_new_2', 'column_new_3']
new_vals = [np.nan, 'dogs', 3]
df = df.reindex(columns=df.columns.tolist() + new_cols) # add empty cols
df[new_cols] = new_vals # multi-column assignment works for existing cols
8) No final, é difícil vencer três atribuições separadas:
df['column_new_1'] = np.nan
df['column_new_2'] = 'dogs'
df['column_new_3'] = 3
Nota: muitas dessas opções já foram abordadas em outras respostas: Adicionar várias colunas ao DataFrame e defini-las iguais a uma coluna existente . É possível adicionar várias colunas de uma vez a um DataFrame do pandas? , Adicionar várias colunas vazias ao DataFrame do pandas
KeyError: "None of [Index(['column_new_1', 'column_new_2', 'column_new_3'], dtype='object')] are in the [columns]"