Agregue múltiples columnas vacías a pandas DataFrame

Esta puede ser una pregunta estúpida, pero ¿cómo agrego varias columnas vacías a un DataFrame de una lista?

Puedo hacer:

df["B"] = None df["C"] = None df["D"] = None 

Pero no puedo hacer:

 df[["B", "C", "D"]] = None KeyError: "['B' 'C' 'D'] not in index" 

Me gustaría utilizar 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: [] 

Entonces, al pasar una lista que contiene su df original y una nueva con las columnas que desea agregar, esto devolverá un nuevo df con las columnas adicionales.


Advertencia: vea la discusión de desempeño en las otras respuestas y / o las discusiones de comentarios. reindex puede ser preferible cuando el rendimiento es crítico.

Podría usar df.reindex para agregar nuevas columnas:

 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]: ABCD 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 devolverá un nuevo DataFrame, con columnas que aparecen en el orden en que aparecen:

 In [31]: df.reindex(columns=list('DCBA')) Out[31]: DCBA 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 

El método de fill_value como un parámetro de valor de fill_value también:

 In [22]: df.reindex(columns=list('ABCD'), fill_value=0) Out[22]: ABCD 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 no desea volver a escribir el nombre de las columnas antiguas , puede usar reindexar:

 df.reindex(columns=[*df.columns.tolist(), 'new_column1', 'new_column2'], fill_value=0) 

Ejemplo completo :

 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 

Y, si ya tiene una lista con los nombres de las columnas,:

 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 

Un problema menor que tengo con la respuesta de @ unutbu de reindexar es que debe pasar una lista de los nombres de columna existentes junto con los nuevos al método de reindex . Si intentas no codificar esto, deberías usar la respuesta de @toto_tico.

 df = pd.DataFrame({'A': ['x', 'x', 'x', 'x']}) df A 0 x 1 x 2 x 3 x 

 newcols = ['B', 'C', 'D'] df.reindex([*df.columns, *newcols], axis=1) ABCD 0 x NaN NaN NaN 1 x NaN NaN NaN 2 x NaN NaN NaN 3 x NaN NaN NaN 

Esto es un poco de un bocado. Así que simplemente DataFrame.assign solución de desempaquetado en el pequeño diccionario con DataFrame.assign .

 df.assign(**dict.fromkeys(newcols, np.nan)) ABCD 0 x NaN NaN NaN 1 x NaN NaN NaN 2 x NaN NaN NaN 3 x NaN NaN NaN 

Que es un poco más conciso de especificar. También es fácil especificar un valor predeterminado,

 df.assign(**dict.fromkeys(newcols, 0)) ABCD 0 x 0 0 0 1 x 0 0 0 2 x 0 0 0 3 x 0 0 0 

… o valores por defecto para cada columna.

 newcols = ['B', 'C', 'D'] defaults = ['w', 'y', 'z'] df.assign(**dict(zip(newcols, defaults))) # df.assign(**{'B': 'w', 'C': 'y', 'D': 'z'}) # df.assign(B='w', C='y', D='z') ABCD 0 xwyz 1 xwyz 2 xwyz 3 xwyz 

Tenga en cuenta que hay bastantes formas de especificar nuevas columnas mediante la assign . Prefiero el método de desempaquetado del diccionario ya que le permite especificar nombres arbitrarios para columnas (enteros, caracteres especiales / espacios en blanco, etc.).