web-dev-qa-db-fra.com

Pandas: Ajouter plusieurs colonnes vides à DataFrame

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"
40
Winterflags

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.

36
EdChum

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
49
unutbu

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
13
toto_tico

Pourquoi ne pas simplement utiliser la boucle:

for newcol in ['B','C','D']:
    df[newcol]=0
1
alexprice

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.

0
coldspeed