Je me serais attendu à ce que votre syntaxe fonctionne aussi. Le problème se pose car lorsque vous créez de nouvelles colonnes avec la syntaxe de la liste de colonnes ( df[[new1, new2]] = ...
), les pandas exigent que le côté droit soit un DataFrame (notez que cela n'a pas vraiment d'importance si les colonnes du DataFrame ont les mêmes noms que les colonnes vous créez).
Votre syntaxe fonctionne bien pour attribuer des valeurs scalaires aux colonnes existantes , et pandas est également heureux d'attribuer des valeurs scalaires à une nouvelle colonne en utilisant la syntaxe à colonne unique ( df[new1] = ...
). La solution consiste donc soit à convertir cela en plusieurs affectations à une seule colonne, soit à créer un DataFrame approprié pour le côté droit.
Voici plusieurs approches qui vont travailler:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'col_1': [0, 1, 2, 3],
'col_2': [4, 5, 6, 7]
})
Puis l'un des éléments suivants:
1) Trois affectations en une, en utilisant le déballage de liste:
df['column_new_1'], df['column_new_2'], df['column_new_3'] = [np.nan, 'dogs', 3]
2) DataFrame
développe commodément une seule ligne pour correspondre à l'index, vous pouvez donc le faire:
df[['column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame([[np.nan, 'dogs', 3]], index=df.index)
3) Créez un bloc de données temporaire avec de nouvelles colonnes, puis combinez-le avec le bloc de données d'origine plus tard:
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) Similaire au précédent, mais en utilisant à la join
place de concat
(peut être moins efficace):
df = df.join(pd.DataFrame(
[[np.nan, 'dogs', 3]],
index=df.index,
columns=['column_new_1', 'column_new_2', 'column_new_3']
))
5) Utiliser un dict est une façon plus "naturelle" de créer le nouveau bloc de données que les deux précédents, mais les nouvelles colonnes seront triées par ordre alphabétique (au moins avant 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) À utiliser .assign()
avec plusieurs arguments de colonne.
J'aime beaucoup cette variante sur la réponse de @ zero, mais comme la précédente, les nouvelles colonnes seront toujours triées par ordre alphabétique, du moins avec les premières versions de 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) En fin de compte, il est difficile de battre trois missions distinctes:
df['column_new_1'] = np.nan
df['column_new_2'] = 'dogs'
df['column_new_3'] = 3
Remarque: beaucoup de ces options ont déjà été couvertes dans d'autres réponses: ajoutez plusieurs colonnes à DataFrame et définissez-les égales à une colonne existante , est-il possible d'ajouter plusieurs colonnes à la fois à un pandas DataFrame? , Ajoutez plusieurs colonnes vides à pandas DataFrame
KeyError: "None of [Index(['column_new_1', 'column_new_2', 'column_new_3'], dtype='object')] are in the [columns]"