Dado un DataFrame:
np.random.seed(0)
df = pd.DataFrame(np.random.randn(3, 3), columns=list('ABC'), index=[1, 2, 3])
df
A B C
1 1.764052 0.400157 0.978738
2 2.240893 1.867558 -0.977278
3 0.950088 -0.151357 -0.103219
¿Cuál es la forma más sencilla de agregar una nueva columna que contenga un valor constante, por ejemplo, 0?
A B C new
1 1.764052 0.400157 0.978738 0
2 2.240893 1.867558 -0.977278 0
3 0.950088 -0.151357 -0.103219 0
Esta es mi solución, pero no sé por qué esto coloca a NaN en la columna 'nueva'.
df['new'] = pd.Series([0 for x in range(len(df.index))])
A B C new
1 1.764052 0.400157 0.978738 0.0
2 2.240893 1.867558 -0.977278 0.0
3 0.950088 -0.151357 -0.103219 NaN

df['new'] = pd.Series([0 for x in range(len(df.index))], index=df.index).[0] * len(df.index)df['new'] = 0Respuestas:
La razón por la que esto se coloca
NaNen una columna es porquedf.indexy losIndexde su objeto del lado derecho son diferentes. @zach muestra la forma correcta de asignar una nueva columna de ceros. En general,pandasintenta hacer la mayor alineación de índices posible. Una desventaja es que cuando los índices no están alineados, obtienesNaNdonde no están alineados. Experimente con los métodosreindexyalignpara obtener algo de intuición sobre los trabajos de alineación con objetos que tienen índices alineados parcial, totalmente y no alineados. Por ejemplo, así es comoDataFrame.align()funciona con índices parcialmente alineados:In [7]: from pandas import DataFrame In [8]: from numpy.random import randint In [9]: df = DataFrame({'a': randint(3, size=10)}) In [10]: In [10]: df Out[10]: a 0 0 1 2 2 0 3 1 4 0 5 0 6 0 7 0 8 0 9 0 In [11]: s = df.a[:5] In [12]: dfa, sa = df.align(s, axis=0) In [13]: dfa Out[13]: a 0 0 1 2 2 0 3 1 4 0 5 0 6 0 7 0 8 0 9 0 In [14]: sa Out[14]: 0 0 1 2 2 0 3 1 4 0 5 NaN 6 NaN 7 NaN 8 NaN 9 NaN Name: a, dtype: float64fuente
Asignación in situ súper simple:
df['new'] = 0Para modificaciones in situ, realice una asignación directa. Esta asignación es transmitida por pandas para cada fila.
df = pd.DataFrame('x', index=range(4), columns=list('ABC')) df A B C 0 x x x 1 x x x 2 x x x 3 x x xdf['new'] = 'y' # Same as, # df.loc[:, 'new'] = 'y' df A B C new 0 x x x y 1 x x x y 2 x x x y 3 x x x yNota para columnas de objetos
Si desea agregar una columna de listas vacías, este es mi consejo:
objectlas columnas son malas noticias en términos de rendimiento. Reconsidere cómo se estructuran sus datos.Si debe almacenar una columna de listas, asegúrese de no copiar la misma referencia varias veces.
# Wrong df['new'] = [[]] * len(df) # Right df['new'] = [[] for _ in range(len(df))]Generando una copia:
df.assign(new=0)Si necesita una copia en su lugar, use
DataFrame.assign:df.assign(new='y') A B C new 0 x x x y 1 x x x y 2 x x x y 3 x x x yY, si necesita asignar varias columnas con el mismo valor, esto es tan simple como,
c = ['new1', 'new2', ...] df.assign(**dict.fromkeys(c, 'y')) A B C new1 new2 0 x x x y y 1 x x x y y 2 x x x y y 3 x x x y yAsignación de varias columnas
Por último, si necesita asignar varias columnas con diferentes valores, puede utilizarlo
assigncon un diccionario.c = {'new1': 'w', 'new2': 'y', 'new3': 'z'} df.assign(**c) A B C new1 new2 new3 0 x x x w y z 1 x x x w y z 2 x x x w y z 3 x x x w y zfuente
Con los pandas modernos puedes hacer lo siguiente:
df['new'] = 0fuente
Aquí hay otro trazador de líneas usando lambdas (cree una columna con un valor constante = 10)
df['newCol'] = df.apply(lambda x: 10, axis=1)antes de
df A B C 1 1.764052 0.400157 0.978738 2 2.240893 1.867558 -0.977278 3 0.950088 -0.151357 -0.103219después
df A B C newCol 1 1.764052 0.400157 0.978738 10 2 2.240893 1.867558 -0.977278 10 3 0.950088 -0.151357 -0.103219 10fuente
df['newCol'] = 10también es un trazador de líneas (y es más rápido). ¿Cuál es la ventaja de usar aplicar aquí?df['new'] = [[] for _ in range(len(df))]