Agregar una nueva columna al DataFrame existente en Python pandas

1174

Tengo el siguiente DataFrame indexado con columnas con nombre y filas no números continuos:

          a         b         c         d
2  0.671399  0.101208 -0.181532  0.241273
3  0.446172 -0.243316  0.051767  1.577318
5  0.614758  0.075793 -0.451460 -0.012493

Me gustaría agregar una nueva columna, 'e'al marco de datos existente y no quiero cambiar nada en el marco de datos (es decir, la nueva columna siempre tiene la misma longitud que el marco de datos).

0   -0.335485
1   -1.166658
2   -0.385571
dtype: float64

¿Cómo puedo agregar una columna eal ejemplo anterior?

1
  • si su nueva columna depende de su columna existente, entonces puede agregar sus nuevas columnas como la mía a continuación. Ersin Gülbahar 12 de agosto a las 5:49
1214

Editar 2017

Como se indica en los comentarios y por @Alexander, actualmente el mejor método para agregar los valores de una Serie como una nueva columna de un DataFrame podría ser usar assign:

df1 = df1.assign(e=pd.Series(np.random.randn(sLength)).values)

Editar 2015
Algunos informaron haber obtenido SettingWithCopyWarningcon este código.
Sin embargo, el código aún funciona perfectamente con la versión 0.16.1 de pandas actual.

>>> sLength = len(df1['a'])
>>> df1
          a         b         c         d
6 -0.269221 -0.026476  0.997517  1.294385
8  0.917438  0.847941  0.034235 -0.448948

>>> df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e
6 -0.269221 -0.026476  0.997517  1.294385  1.757167
8  0.917438  0.847941  0.034235 -0.448948  2.228131

>>> pd.version.short_version
'0.16.1'

El SettingWithCopyWarningobjetivo es informar de una posible asignación no válida en una copia del marco de datos. No necesariamente dice que lo hizo mal (puede desencadenar falsos positivos), pero a partir de 0.13.0 le permite saber que hay métodos más adecuados para el mismo propósito. Luego, si recibe la advertencia, simplemente siga su consejo: intente usar .loc [row_index, col_indexer] = value en su lugar

>>> df1.loc[:,'f'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e         f
6 -0.269221 -0.026476  0.997517  1.294385  1.757167 -0.050927
8  0.917438  0.847941  0.034235 -0.448948  2.228131  0.006109
>>> 

De hecho, este es actualmente el método más eficiente como se describe en pandas docs


Respuesta original:

Utilice los índices df1 originales para crear la serie:

df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
27
  • 29
    si necesita anteponer la columna, use DataFrame.insert: df1.insert (0, 'A', Series (np.random.randn (sLength), index = df1.index))lowtech 9/12/2013 a las 21:48
  • 33
    Desde la versión 0.12 de Pandas en adelante, creo que esta sintaxis no es óptima y advierte:SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value insteadZhubarb 19 de enero de 2015 a las 10:59
  • 6
    Seguir .loc como advertencia de SettingWithCopy de alguna manera da como resultado más advertencias: ... self.obj [item_labels [indexer [info_axis]]] = valueseongjoo 3 de febrero de 2016 a las 7:30
  • 12
    @toto_tico Puedes descomprimir un kwargsdiccionario, así:df1 = df1.assign(**{'e': p.Series(np.random.randn(sLength)).values})T.C. Proctor 14 de septiembre de 2017 a las 16:56
  • 26
    En lugar de decir "actualmente" o hacer referencia a los años, haga referencia a los números de versión de los pandas, por ejemplo, "entre 0.14-0.16 do X, en 0.17+ do Y ..."smci 4 de marzo de 2018 a las 23:58
281

Esta es la forma sencilla de agregar una nueva columna: df['e'] = e

6
  • 183
    A pesar del elevado número de votos: esta respuesta es incorrecta . Tenga en cuenta que el OP tiene un marco de datos con índices no continuos y e( Series(np.random.randn(sLength))) genera una Serie 0-n indexada. Si asigna esto a df1, obtendrá algunas celdas NaN. joaquin 26/08/14 a las 22:29
  • 40
    Lo que dice @joaquin es cierto, pero siempre que lo tengas en cuenta, este es un atajo muy útil. VedTopkar 27 de septiembre de 2014 a las 2:37
  • 2
    @Eric Leschinski: No estoy seguro de cómo editar ayudará a esta pregunta. my_dataframe = pd.DataFrame(columns=('foo', 'bar')). Revertir su ediciónKathirmani Sukumar 10 de diciembre de 2016 a las 6:53
  • 1
    No ayuda, porque si tiene varias filas y usa la asignación, asigna todas las filas de la nueva columna con ese valor (en su caso e) que generalmente no es deseable. Paniz 27/04/19 a las 22:42
  • 2
    La cuestión planteada @joaquin anterior simplemente se puede resolver (como en la respuesta de Joaquín arriba) haciendo: df['e'] = e.valueso lo que es equivalente, df['e'] = e.to_numpy(). ¿Derecha? flow2k 1 sep.2020 a las 20:36
189

I would like to add a new column, 'e', to the existing data frame and do not change anything in the data frame. (The series always got the same length as a dataframe.)

Supongo que los valores del índice ecoinciden con los de df1.

La forma más fácil de iniciar una nueva columna nombrada ey asignarle los valores de su serie e:

df['e'] = e.values

asignar (Pandas 0.16.0+)

A partir de Pandas 0.16.0, también puede usar assign, que asigna nuevas columnas a un DataFrame y devuelve un nuevo objeto (una copia) con todas las columnas originales además de las nuevas.

df1 = df1.assign(e=e.values)

Según este ejemplo (que también incluye el código fuente de la assignfunción), también puede incluir más de una columna:

df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
>>> df.assign(mean_a=df.a.mean(), mean_b=df.b.mean())
   a  b  mean_a  mean_b
0  1  3     1.5     3.5
1  2  4     1.5     3.5

En contexto con su ejemplo:

np.random.seed(0)
df1 = pd.DataFrame(np.random.randn(10, 4), columns=['a', 'b', 'c', 'd'])
mask = df1.applymap(lambda x: x <-0.7)
df1 = df1[-mask.any(axis=1)]
sLength = len(df1['a'])
e = pd.Series(np.random.randn(sLength))

>>> df1
          a         b         c         d
0  1.764052  0.400157  0.978738  2.240893
2 -0.103219  0.410599  0.144044  1.454274
3  0.761038  0.121675  0.443863  0.333674
7  1.532779  1.469359  0.154947  0.378163
9  1.230291  1.202380 -0.387327 -0.302303

>>> e
0   -1.048553
1   -1.420018
2   -1.706270
3    1.950775
4   -0.509652
dtype: float64

df1 = df1.assign(e=e.values)

>>> df1
          a         b         c         d         e
0  1.764052  0.400157  0.978738  2.240893 -1.048553
2 -0.103219  0.410599  0.144044  1.454274 -1.420018
3  0.761038  0.121675  0.443863  0.333674 -1.706270
7  1.532779  1.469359  0.154947  0.378163  1.950775
9  1.230291  1.202380 -0.387327 -0.302303 -0.509652

La descripción de esta nueva función cuando se introdujo por primera vez se puede encontrar aquí .

8
  • 4
    ¿Algún comentario sobre el rendimiento relativo de los dos métodos, considerando que el primer método ( df['e'] = e.values) no crea una copia del marco de datos, mientras que la segunda opción (usar df.assign) sí? En los casos en que se agreguen muchas columnas nuevas secuencialmente y marcos de datos grandes, esperaría un rendimiento mucho mejor del primer método. jhin 11 de mayo de 2017 a las 13:05
  • 3
    @jhin Sí, la asignación directa es obviamente mucho si está trabajando en un marco de datos fijo. El beneficio de usar assignes cuando encadena sus operaciones. Alexander 11 de mayo de 2017 a las 19:06
  • Esto ciertamente parece un buen equilibrio entre explícito e implícito. +1: DAbe Hoffman 19 de mayo de 2017 a las 4:03
  • 2
    Para la diversióndf.assign(**df.mean().add_prefix('mean_'))piRSquared 7/11/2017 a las 17:36
  • 2
    @Owlright De la pregunta, parece que el OP simplemente está concatenando los marcos de datos e ignorando el índice. Si este es el caso, los métodos anteriores funcionarán. Si uno desea retener el índice, use algo como df_new = pd.concat([df1, df2], axis=1), notándolo ignore_index=Falsepor defecto. Alexander 7 de nov. De 2018 a las 23:16
66

Asignación de columnas súper simple

Un marco de datos de pandas se implementa como un dictado ordenado de columnas.

Esto significa que __getitem__ []no solo se puede usar para obtener una determinada columna, sino que también __setitem__ [] =se puede usar para asignar una nueva columna.

Por ejemplo, este marco de datos puede tener una columna agregada simplemente usando el descriptor de []acceso

    size      name color
0    big      rose   red
1  small    violet  blue
2  small     tulip   red
3  small  harebell  blue

df['protected'] = ['no', 'no', 'no', 'yes']

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Tenga en cuenta que esto funciona incluso si el índice del marco de datos está desactivado.

df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

[] = es el camino a seguir, ¡pero cuidado!

Sin embargo, si tiene un pd.Seriese intenta asignarlo a un marco de datos donde los índices están apagados, se encontrará con problemas. Ver ejemplo:

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

Esto se debe a que pd.Seriesde forma predeterminada a tiene un índice enumerado de 0 a n. Y el [] =método de los pandas intenta ser "inteligente"

¿Qué está pasando realmente?

Cuando usa el [] =método, pandas está realizando silenciosamente una combinación externa o una combinación externa utilizando el índice del marco de datos de la izquierda y el índice de la serie de la derecha.df['column'] = series

Nota al margen

Esto causa rápidamente una disonancia cognitiva, ya que el []=método intenta hacer muchas cosas diferentes dependiendo de la entrada, y el resultado no se puede predecir a menos que se sepa cómo funcionan los pandas. Por lo tanto, desaconsejaría las []=bases de código en, pero cuando se exploran datos en un cuaderno, está bien.

Dando la vuelta al problema

Si tiene un pd.Seriesy lo quiere asignado de arriba a abajo, o si está codificando un código productivo y no está seguro del orden del índice, vale la pena protegerse de este tipo de problema.

Puede abatir el pd.Seriesa a np.ndarrayo a list, esto hará el truco.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values

o

df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))

Pero esto no es muy explícito.

Algún programador puede venir y decir "Oye, esto parece redundante, lo optimizaré".

Manera explícita

Establecer el índice de pd.Seriespara que sea el índice de dfes explícito.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)

O de manera más realista, probablemente pd.Seriesya tenga un archivo.

protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index

3     no
2     no
1     no
0    yes

Ahora se puede asignar

df['protected'] = protected_series

    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

Manera alternativa con df.reset_index()

Dado que la disonancia del índice es el problema, si cree que el índice del marco de datos no debería dictar las cosas, simplemente puede eliminar el índice, esto debería ser más rápido, pero no es muy limpio, ya que su función ahora probablemente hace dos cosas.

df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Nota sobre df.assign

Si bien df.assignhaz más explícito lo que estás haciendo, en realidad tiene los mismos problemas que los anteriores.[]=

df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

Solo df.assigntenga cuidado con que su columna no se llame self. Causará errores. Esto hace que df.assign huele mal , ya que hay este tipo de artefactos en la función.

df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'

Puede decir: "Bueno, selfentonces no lo usaré ". Pero quién sabe cómo cambia esta función en el futuro para apoyar nuevos argumentos. Tal vez el nombre de su columna sea un argumento en una nueva actualización de pandas, causando problemas con la actualización.

1
  • 7
    " Cuando usas el [] =método, los pandas están realizando silenciosamente una combinación externa o una combinación externa ". Esta es la información más importante de todo el tema. Pero, ¿podría proporcionar un enlace a la documentación oficial sobre cómo []=funciona el operador? Lightman 1 de agosto de 2017 a las 12:27
57

Parece que en las versiones recientes de Pandas, el camino a seguir es usar df.assign :

df1 = df1.assign(e=np.random.randn(sLength))

No produce SettingWithCopyWarning.

1
  • 3
    Copiando el comentario de @smci de arriba ... En lugar de decir "actualmente" o hacer referencia a los años, consulte los números de versión de PandasKyle C 16/01/19 a las 22:07
56

Hacer esto directamente a través de NumPy será lo más eficiente:

df1['e'] = np.random.randn(sLength)

Tenga en cuenta que mi sugerencia original (muy antigua) era usar map(que es mucho más lento):

df1['e'] = df1['a'].map(lambda x: np.random.random())
2
  • 1
    gracias por su respuesta, como ya he dado, ¿puedo modificar su código .mappara usar series existentes en lugar de lambda? Lo intento df1['e'] = df1['a'].map(lambda x: e)o df1['e'] = df1['a'].map(e)pero no es lo que necesito. (Soy nuevo en Pyhon y su respuesta anterior ya me ayudó)tomasz74 23/09/12 a las 20:03
  • @ tomasz74 si ya tiene euna serie, entonces no necesita usar map, use df['e']=e(@joaquins answer). Andy Hayden 23/09/12 a las 20:33
38

Maneras más fáciles: -

data['new_col'] = list_of_values

data.loc[ : , 'new_col'] = list_of_values

De esta manera, evita lo que se denomina indexación encadenada al establecer nuevos valores en un objeto pandas. Haga clic aquí para leer más .

25

SettingWithCopyWarningObtuve el temido , y no se solucionó usando la sintaxis iloc. Mi DataFrame fue creado por read_sql a partir de una fuente ODBC. Usando una sugerencia de lowtech anterior, lo siguiente funcionó para mí:

df.insert(len(df.columns), 'e', pd.Series(np.random.randn(sLength),  index=df.index))

Esto funcionó bien para insertar la columna al final. No sé si es el más eficiente, pero no me gustan los mensajes de advertencia. Creo que hay una solución mejor, pero no puedo encontrarla y creo que depende de algún aspecto del índice.
Nota . Que esto solo funciona una vez y dará un mensaje de error si intenta sobrescribir una columna existente.
Nota Como arriba y desde 0.16.0, asignar es la mejor solución. Consulte la documentación http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.assign.html#pandas.DataFrame.assign Funciona bien para el tipo de flujo de datos en el que no sobrescribe sus valores intermedios.

0
25

Si desea establecer toda la nueva columna en un valor base inicial (por ejemplo None), puede hacer esto:df1['e'] = None

En realidad, esto asignaría el tipo de "objeto" a la celda. Entonces, más tarde, puede colocar tipos de datos complejos, como una lista, en celdas individuales.

2
  • 2
    esto genera una configuración con una advertencia de copia00__00__00 2 de mayo de 2018 a las 14:27
  • 2
    df ['E'] = '' también funciona si alguien quiere agregar una columna vacíadebaonline4u 4 de septiembre de 2018 a las 9:29
16
  1. Primero cree una pitón list_of_eque tenga datos relevantes.
  2. Utilizar esta: df['e'] = list_of_e
1
  • 1
    Realmente no entiendo por qué esta no es la respuesta preferida. En caso de que tenga un pd.Series, el tolist()comando puede ser útil. So S 23 de mayo de 2019 a las 16:01
14

Si la columna que está intentando agregar es una variable de serie, simplemente:

df["new_columns_name"]=series_variable_name #this will do it for you

Esto funciona bien incluso si está reemplazando una columna existente. Simplemente escriba new_columns_name igual que la columna que desea reemplazar. Simplemente sobrescribirá los datos de la columna existente con los datos de la nueva serie.

13

Si el marco de datos y el objeto Serie tienen el mismo índice , pandas.concattambién funciona aquí:

import pandas as pd
df
#          a            b           c           d
#0  0.671399     0.101208   -0.181532    0.241273
#1  0.446172    -0.243316    0.051767    1.577318
#2  0.614758     0.075793   -0.451460   -0.012493

e = pd.Series([-0.335485, -1.166658, -0.385571])    
e
#0   -0.335485
#1   -1.166658
#2   -0.385571
#dtype: float64

# here we need to give the series object a name which converts to the new  column name 
# in the result
df = pd.concat([df, e.rename("e")], axis=1)
df

#          a            b           c           d           e
#0  0.671399     0.101208   -0.181532    0.241273   -0.335485
#1  0.446172    -0.243316    0.051767    1.577318   -1.166658
#2  0.614758     0.075793   -0.451460   -0.012493   -0.385571

En caso de que no tengan el mismo índice:

e.index = df.index
df = pd.concat([df, e.rename("e")], axis=1)
13

Para crear una columna vacía

df['i'] = None
0
12

Infalible:

df.loc[:, 'NewCol'] = 'New_Val'

Ejemplo:

df = pd.DataFrame(data=np.random.randn(20, 4), columns=['A', 'B', 'C', 'D'])

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
3  -0.147354  0.778707  0.479145  2.284143
4  -0.529529  0.000571  0.913779  1.395894
5   2.592400  0.637253  1.441096 -0.631468
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
8   0.606985 -2.232903 -1.358107 -2.855494
9  -0.692013  0.671866  1.179466 -1.180351
10 -1.093707 -0.530600  0.182926 -1.296494
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
18  0.693458  0.144327  0.329500 -0.655045
19  0.104425  0.037412  0.450598 -0.923387


df.drop([3, 5, 8, 10, 18], inplace=True)

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
4  -0.529529  0.000571  0.913779  1.395894
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
9  -0.692013  0.671866  1.179466 -1.180351
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
19  0.104425  0.037412  0.450598 -0.923387

df.loc[:, 'NewCol'] = 0

df
           A         B         C         D  NewCol
0  -0.761269  0.477348  1.170614  0.752714       0
1   1.217250 -0.930860 -0.769324 -0.408642       0
2  -0.619679 -1.227659 -0.259135  1.700294       0
4  -0.529529  0.000571  0.913779  1.395894       0
6   0.757178  0.240012 -0.553820  1.177202       0
7  -0.986128 -1.313843  0.788589 -0.707836       0
9  -0.692013  0.671866  1.179466 -1.180351       0
11 -0.143273 -0.503199 -1.328728  0.610552       0
12 -0.923110 -1.365890 -1.366202 -1.185999       0
13 -2.026832  0.273593 -0.440426 -0.627423       0
14 -0.054503 -0.788866 -0.228088 -0.404783       0
15  0.955298 -1.430019  1.434071 -0.088215       0
16 -0.227946  0.047462  0.373573 -0.111675       0
17  1.627912  0.043611  1.743403 -0.012714       0
19  0.104425  0.037412  0.450598 -0.923387       0
1
  • 2
    No infalible. Esto no aborda la pregunta del OP, que es un caso en el que los índices del marco de datos existente y la nueva serie no están alineados. Alexander 1 oct 2018 a las 19:17
10

Sin embargo, una cosa a tener en cuenta es que si lo hace

df1['e'] = Series(np.random.randn(sLength), index=df1.index)

esto será efectivamente una combinación izquierda en el df1.index. Entonces, si desea tener un efecto de combinación externa , mi solución probablemente imperfecta es crear un marco de datos con valores de índice que cubran el universo de sus datos y luego usar el código anterior. Por ejemplo,

data = pd.DataFrame(index=all_possible_values)
df1['e'] = Series(np.random.randn(sLength), index=df1.index)
9

para insertar una nueva columna en una ubicación determinada (0 <= loc <= cantidad de columnas) en un marco de datos, solo use Dataframe.insert:

DataFrame.insert(loc, column, value)

Por lo tanto, si desea agregar la columna e al final de un marco de datos llamado df , puede usar:

e = [-0.335485, -1.166658, -0.385571]    
DataFrame.insert(loc=len(df.columns), column='e', value=e)

el valor puede ser una serie, un número entero (en cuyo caso todas las celdas se llenan con este valor) o una estructura similar a una matriz

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.insert.html

8

Permítanme agregar que, al igual que para hum3 , .locno resolvió el SettingWithCopyWarningy tuve que recurrir a él df.insert(). En mi caso, el falso positivo fue generado por la indexación de la cadena "falsa" dict['a']['e'], donde 'e'está la nueva columna, y dict['a']es un DataFrame proveniente del diccionario.

También tenga en cuenta que si sabe lo que está haciendo, puede cambiar la advertencia usando pd.options.mode.chained_assignment = None y luego usar una de las otras soluciones que se proporcionan aquí.

7

Antes de asignar una nueva columna, si tiene datos indexados, debe ordenar el índice. Al menos en mi caso tuve que:

data.set_index(['index_column'], inplace=True)
"if index is unsorted, assignment of a new column will fail"        
data.sort_index(inplace = True)
data.loc['index_value1', 'column_y'] = np.random.randn(data.loc['index_value1', 'column_x'].shape[0])
6

Para agregar una nueva columna, 'e', ​​al marco de datos existente

 df1.loc[:,'e'] = Series(np.random.randn(sLength))
2
  • También da el mensaje de advertenciaB Furtado 29 de agosto de 2017 a las 14:25
  • debe usar df1.loc [::, 'e'] = Series (np.random.randn (sLength))Hermes Morales 27 abr.20 a las 14:08
6

Estaba buscando una forma general de agregar una columna de numpy.nansa un marco de datos sin ser tonto SettingWithCopyWarning.

De lo siguiente:

  • las respuestas aquí
  • esta pregunta sobre pasar una variable como argumento de palabra clave
  • este método para generar una numpymatriz de NaN en línea

Se me ocurrió esto:

col = 'column_name'
df = df.assign(**{col:numpy.full(len(df), numpy.nan)})
5

En aras de la integridad, otra solución más utilizando el método DataFrame.eval () :

Datos:

In [44]: e
Out[44]:
0    1.225506
1   -1.033944
2   -0.498953
3   -0.373332
4    0.615030
5   -0.622436
dtype: float64

In [45]: df1
Out[45]:
          a         b         c         d
0 -0.634222 -0.103264  0.745069  0.801288
4  0.782387 -0.090279  0.757662 -0.602408
5 -0.117456  2.124496  1.057301  0.765466
7  0.767532  0.104304 -0.586850  1.051297
8 -0.103272  0.958334  1.163092  1.182315
9 -0.616254  0.296678 -0.112027  0.679112

Solución:

In [46]: df1.eval("e = @e.values", inplace=True)

In [47]: df1
Out[47]:
          a         b         c         d         e
0 -0.634222 -0.103264  0.745069  0.801288  1.225506
4  0.782387 -0.090279  0.757662 -0.602408 -1.033944
5 -0.117456  2.124496  1.057301  0.765466 -0.498953
7  0.767532  0.104304 -0.586850  1.051297 -0.373332
8 -0.103272  0.958334  1.163092  1.182315  0.615030
9 -0.616254  0.296678 -0.112027  0.679112 -0.622436
4

Lo siguiente es lo que hice ... Pero soy bastante nuevo en pandas y realmente Python en general, así que no hay promesas.

df = pd.DataFrame([[1, 2], [3, 4], [5,6]], columns=list('AB'))

newCol = [3,5,7]
newName = 'C'

values = np.insert(df.values,df.shape[1],newCol,axis=1)
header = df.columns.values.tolist()
header.append(newName)

df = pd.DataFrame(values,columns=header)
3

Si obtiene el SettingWithCopyWarning, una solución fácil es copiar el DataFrame al que está tratando de agregar una columna.

df = df.copy()
df['col_name'] = values
1
  • 10
    Esa no es una buena idea. Si el marco de datos es lo suficientemente grande, consumirá mucha memoria ... Además, se convertiría en una pesadilla si sigues agregando columnas de vez en cuando. Kevad 21/04/2016 a las 12:56
3
x=pd.DataFrame([1,2,3,4,5])

y=pd.DataFrame([5,4,3,2,1])

z=pd.concat([x,y],axis=1)

ingrese la descripción de la imagen aquí

1
  • Dudo que esto ayude, o incluso que funcione en absoluto. ¿Le importaria explicar? Yunnosch 4/10/20 a las 10:41
3

Si solo necesita crear una nueva columna vacía, la solución más corta es:

df.loc[:, 'e'] = pd.Series()
3

Si queremos asignar un valor de escala, por ejemplo: 10 a todas las filas de una nueva columna en un df:

df = df.assign(new_col=lambda x:10)  # x is each row passed in to the lambda func

df ahora tendrá una nueva columna 'new_col' con valor = 10 en todas las filas.

2

este es un caso especial de agregar una nueva columna a un marco de datos de pandas. Aquí, estoy agregando una nueva característica / columna basada en los datos de una columna existente del marco de datos.

entonces, dejemos que nuestro dataFrame tenga columnas 'feature_1', 'feature_2', 'chance_score' y tenemos que agregar una nueva_columna 'predicted_class' basada en los datos de la columna 'probabilidad_score'.

Usaré la función map () de Python y también definiré una función propia que implementará la lógica sobre cómo dar un class_label particular a cada fila en mi dataFrame.

data = pd.read_csv('data.csv')

def myFunction(x):
   //implement your logic here

   if so and so:
        return a
   return b

variable_1 = data['probability_score']
predicted_class = variable_1.map(myFunction)

data['predicted_class'] = predicted_class

// check dataFrame, new column is included based on an existing column data for each row
data.head()
0

Siempre que agregue un objeto Serie como una nueva columna a un DF existente, debe asegurarse de que ambos tengan el mismo índice. Luego agrégalo al DF

e_series = pd.Series([-0.335485, -1.166658,-0.385571])
print(e_series)
e_series.index = d_f.index
d_f['e'] = e_series
d_f

ingrese la descripción de la imagen aquí

0

puede insertar una nueva columna por bucle for como este:

for label,row in your_dframe.iterrows():
      your_dframe.loc[label,"new_column_length"]=len(row["any_of_column_in_your_dframe"])

código de muestra aquí:

import pandas as pd

data = {
  "any_of_column_in_your_dframe" : ["ersingulbahar","yagiz","TS"],
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}

#load data into a DataFrame object:
your_dframe = pd.DataFrame(data)


for label,row in your_dframe.iterrows():
      your_dframe.loc[label,"new_column_length"]=len(row["any_of_column_in_your_dframe"])
      
      
print(your_dframe) 

y la salida está aquí:

any_of_column_in_your_dframe calorías duración new_column_length
ersingulbahar 420 50 13,0
yagiz 380 40 5,0
TS 390 45 2.0

No: también puedes usarlo así:

your_dframe["new_column_length"]=your_dframe["any_of_column_in_your_dframe"].apply(len)