C'est peut-être une question stupide, mais comment puis-je ajouter plusieurs colonnes vides à un DataFrame à partir d'une liste?
Je peux faire:
df["B"] = None
df["C"] = None
df["D"] = None
Mais je ne peux pas faire:
df[["B", "C", "D"]] = None
KeyError: "['B' 'C' 'D'] not in index"
Je concat
en utilisant un DataFrame:
In [23]:
df = pd.DataFrame(columns=['A'])
df
Out[23]:
Empty DataFrame
Columns: [A]
Index: []
In [24]:
pd.concat([df,pd.DataFrame(columns=list('BCD'))])
Out[24]:
Empty DataFrame
Columns: [A, B, C, D]
Index: []
Donc, en passant une liste contenant votre df original et une nouvelle liste avec les colonnes que vous souhaitez ajouter, cela retournera un nouveau df avec les colonnes supplémentaires.
Mise en garde: voir la discussion sur la performance dans les autres discussions réponses et/ou les commentaires. reindex
peut être préférable lorsque les performances sont critiques.
Vous pouvez utiliser df.reindex
pour ajouter de nouvelles colonnes:
In [18]: df = pd.DataFrame(np.random.randint(10, size=(5,1)), columns=['A'])
In [19]: df
Out[19]:
A
0 4
1 7
2 0
3 7
4 6
In [20]: df.reindex(columns=list('ABCD'))
Out[20]:
A B C D
0 4 NaN NaN NaN
1 7 NaN NaN NaN
2 0 NaN NaN NaN
3 7 NaN NaN NaN
4 6 NaN NaN NaN
reindex
retournera un nouveau DataFrame, avec les colonnes apparaissant dans l'ordre dans lequel elles sont listées:
In [31]: df.reindex(columns=list('DCBA'))
Out[31]:
D C B A
0 NaN NaN NaN 4
1 NaN NaN NaN 7
2 NaN NaN NaN 0
3 NaN NaN NaN 7
4 NaN NaN NaN 6
La méthode reindex
en tant que paramètre fill_value
:
In [22]: df.reindex(columns=list('ABCD'), fill_value=0)
Out[22]:
A B C D
0 4 0 0 0
1 7 0 0 0
2 0 0 0 0
3 7 0 0 0
4 6 0 0 0
Si vous ne voulez pas réécrire le nom des anciennes colonnes , vous pouvez utiliser reindex:
df.reindex(columns=[*df.columns.tolist(), 'new_column1', 'new_column2'], fill_value=0)
Exemple complet:
In [1]: df = pd.DataFrame(np.random.randint(10, size=(3,1)), columns=['A'])
In [1]: df
Out[1]:
A
0 4
1 7
2 0
In [2]: df.reindex(columns=[*df.columns.tolist(), 'col1', 'col2'], fill_value=0)
Out[2]:
A col1 col2
0 1 0 0
1 2 0 0
Et, si vous avez déjà une liste avec les noms de colonne,:
In [3]: my_cols_list=['col1','col2']
In [4]: df.reindex(columns=[*df.columns.tolist(), *my_cols_list], fill_value=0)
Out[4]:
A col1 col2
0 1 0 0
1 2 0 0
Pourquoi ne pas simplement utiliser la boucle:
for newcol in ['B','C','D']:
df[newcol]=0
Un nit mineur que j'ai avec la réponse de @ unutbu de reindex
est, pour réindexer le DataFrame, vous devez passer une liste des noms de colonnes existants avec les nouveaux.
Si vous essayez de ne pas coder cela en dur, vous devrez utiliser la réponse de @ toto_tico, qui ressemble à quelque chose comme:
newcols = ['B', 'C', 'D']
df.reindex([*df.columns, *newcols], axis=1)
price B C D
0 10 NaN NaN NaN
1 13 NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 9 NaN NaN NaN
C'est un peu une bouchée. Je vais donc simplement ajouter cette jolie solution de décompression de dictionnaire avec DataFrame.assign
.
df.assign(**dict.fromkeys(newcols, np.nan))
price B C D
0 10 NaN NaN NaN
1 13 NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 9 NaN NaN NaN
Ce qui est un peu plus concis à préciser.