Mi sarei aspettato che anche la tua sintassi funzionasse. Il problema sorge perché quando crei nuove colonne con la sintassi dell'elenco di colonne ( df[[new1, new2]] = ...), panda richiede che il lato destro sia un DataFrame (nota che in realtà non importa se le colonne del DataFrame hanno gli stessi nomi delle colonne stai creando).
La tua sintassi funziona bene per assegnare valori scalari a colonne esistenti e panda è anche felice di assegnare valori scalari a una nuova colonna usando la sintassi a colonna singola ( df[new1] = ...). Quindi la soluzione è convertire questo in diverse assegnazioni a colonna singola o creare un DataFrame adatto per il lato destro.
Qui ci sono diversi approcci che sarà lavorare:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'col_1': [0, 1, 2, 3],
'col_2': [4, 5, 6, 7]
})
Quindi uno dei seguenti:
1) Tre incarichi in uno, utilizzando lo spacchettamento dell'elenco:
df['column_new_1'], df['column_new_2'], df['column_new_3'] = [np.nan, 'dogs', 3]
2) DataFrameespande comodamente una singola riga in modo che corrisponda all'indice, quindi puoi farlo:
df[['column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame([[np.nan, 'dogs', 3]], index=df.index)
3) Crea un data frame temporaneo con nuove colonne, quindi combinalo con il data frame originale in un secondo momento:
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) Simile al precedente, ma usando joininvece di concat(potrebbe essere meno efficiente):
df = df.join(pd.DataFrame(
[[np.nan, 'dogs', 3]],
index=df.index,
columns=['column_new_1', 'column_new_2', 'column_new_3']
))
5) Usare un dict è un modo più "naturale" per creare il nuovo data frame rispetto ai due precedenti, ma le nuove colonne saranno ordinate alfabeticamente (almeno prima di Python 3.6 o 3.7 ):
df = df.join(pd.DataFrame(
{
'column_new_1': np.nan,
'column_new_2': 'dogs',
'column_new_3': 3
}, index=df.index
))
6) Utilizzare .assign()con più argomenti di colonna.
Mi piace molto questa variante alla risposta di @ zero, ma come la precedente, le nuove colonne saranno sempre ordinate alfabeticamente, almeno con le prime versioni di 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) Alla fine è difficile battere tre incarichi separati:
df['column_new_1'] = np.nan
df['column_new_2'] = 'dogs'
df['column_new_3'] = 3
Nota: molte di queste opzioni sono già state trattate in altre risposte: Aggiungi più colonne a DataFrame e impostale uguali a una colonna esistente , è possibile aggiungere più colonne contemporaneamente a un DataFrame panda? , Aggiungi più colonne vuote a panda DataFrame
KeyError: "None of [Index(['column_new_1', 'column_new_2', 'column_new_3'], dtype='object')] are in the [columns]"