Agregar columna en el marco de datos de la lista

95

Tengo un marco de datos con algunas columnas como esta:

A   B   C  
0   
4
5
6
7
7
6
5

El rango posible de valores en A es solo de 0 a 7 .

Además, tengo una lista de 8 elementos como este:

List=[2,5,6,8,12,16,26,32]  //There are only 8 elements in this list

Si el elemento en la columna A es n , necesito insertar el n- ésimo elemento de la Lista en una nueva columna, diga 'D'.

¿Cómo puedo hacer esto de una vez sin recorrer todo el marco de datos?

El marco de datos resultante se vería así:

A   B   C   D
0           2
4           12
5           16
6           26
7           32
7           32
6           26
5           16

Nota: El marco de datos es enorme y la iteración es la última opción. Pero también puedo organizar los elementos en 'Lista' en cualquier otra estructura de datos como dict si es necesario.

melena
fuente
1
Creo que necesitas un ejemplo de juguete (más pequeño), con el resultado deseado. Suena un poco atm vago.
Andy Hayden
11
Nunca llame a una variable "Lista". En cualquier idioma.
lucid_dreamer

Respuestas:

51

IIUC, si convierte su (desafortunadamente nombrado) Listen un ndarray, simplemente puede indexarlo de forma natural.

>>> import numpy as np
>>> m = np.arange(16)*10
>>> m[df.A]
array([  0,  40,  50,  60, 150, 150, 140, 130])
>>> df["D"] = m[df.A]
>>> df
    A   B   C    D
0   0 NaN NaN    0
1   4 NaN NaN   40
2   5 NaN NaN   50
3   6 NaN NaN   60
4  15 NaN NaN  150
5  15 NaN NaN  150
6  14 NaN NaN  140
7  13 NaN NaN  130

Aquí construí uno nuevo m, pero si lo usa m = np.asarray(List), lo mismo debería funcionar: los valores en df.Aseleccionarán los elementos apropiados de m.


Tenga en cuenta que si está usando una versión anterior de numpy, es posible que m[df.A.values]deba usar en su lugar; en el pasado, numpyno funcionó bien con otros, y algunas refactorizaciones pandascausaron algunos dolores de cabeza. Las cosas han mejorado ahora.

DSM
fuente
Hola @DSM. Entiendo lo que está diciendo, pero estoy recibiendo este error: Traceback (most recent call last): File "./b.py", line 24, in <module> d["D"] = m[d.A] IndexError: unsupported iterator index
crines
1
@mane: urf, eso es un numpyerror antiguo . ¿ d["D"] = m[d.A.values]Funciona para ti?
DSM
277

Simplemente asigne la lista directamente:

df['new_col'] = mylist

Alternativa
Convierta la lista en una serie o matriz y luego asigne:

se = pd.Series(mylist)
df['new_col'] = se.values

o

df['new_col'] = np.array(mylist)
gorrión
fuente
3
pykernel_launcher.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy """Entry point for launching an IPython kernel.
Ilya Rusin
@sparrow ¿usará el pd.Seriesefecto del dtype? Quiero decir, ¿dejará flotadores como flotadores y cuerdas como cuerdas? ¿O los elementos dentro de la lista serán cadenas por defecto?
3kstc
2
@IlyaRusin, es un falso positivo que se puede ignorar en este caso. Para obtener más información: stackoverflow.com/questions/20625582/…
sparrow
1
Esto se puede simplificar a: df ['new_col'] = pd.Series (mylist) .values
smartse
16

Una solución que mejora la excelente de @sparrow.

Deje que df sea ​​su conjunto de datos y mylist la lista con los valores que desea agregar al marco de datos.

Supongamos que desea llamar a su nueva columna simplemente, new_column

Primero convierta la lista en una serie:

column_values = pd.Series(mylist)

Luego use la función de inserción para agregar la columna. Esta función tiene la ventaja de permitirle elegir en qué posición desea colocar la columna. En el siguiente ejemplo colocaremos la nueva columna en la primera posición desde la izquierda (estableciendo loc = 0)

df.insert(loc=0, column='new_column', value=column_values)
Salvatore Cosentino
fuente
Esto no funcionará si cambió sus índices de df a algo que no sea 1,2,3 ... en ese caso, debe agregar entre las líneas: column_values.index = df.index
Guy s
8

Primero, creemos el marco de datos que tenía, ignoraré las columnas B y C ya que no son relevantes.

df = pd.DataFrame({'A': [0, 4, 5, 6, 7, 7, 6,5]})

Y el mapeo que deseas:

mapping = dict(enumerate([2,5,6,8,12,16,26,32]))

df['D'] = df['A'].map(mapping)

¡Hecho!

print df

Salida:

   A   D
0  0   2
1  4  12
2  5  16
3  6  26
4  7  32
5  7  32
6  6  26
7  5  16
Phil Cooper
fuente
1
Creo que el OP ya sabe cómo hacer esto. Según mi lectura, el problema se construye a Dpartir de los elementos de Ay List("Si el elemento de la columna A es n, necesito insertar el n-ésimo elemento de la Lista en una nueva columna, diga 'D'")
DSM
SO se ha convertido en una especie de F (* & estado de niñera. Gracias a @DSM por el comentario, pero no pude corregir la publicación hasta que fue revisada por pares. Y luego fue rechazada porque era demasiado rápida. Y luego fui capaz de revisar mi propia edición. Y luego es demasiado tarde porque una respuesta peor (en mi humilde opinión) fue "aceptada". ¡¡¡Así que realmente tengo algunas meta-niñeras que son menos que útiles!
Phil Cooper
Bueno, no puedo hablar por las niñeras, pero encontrará que su enfoque es un orden de magnitud más lento en matrices largas. En otros aspectos, por supuesto, elegir entre np.array(List)[df.A]y df["A"].map(dict(enumerate(List)))es principalmente una cuestión de preferencia.
DSM
Hola, Phil, solo vi tu solución y el comentario de DSM y nunca volví a ella, ya que la solución de DSM funcionó bien para mí. Pero ahora, mirando su solución, también funciona. He ejecutado la solución de DSM en mi conjunto de datos de aproximadamente 200k entradas y se ejecuta en un par de segundos con todos los demás cálculos que tengo. Soy totalmente nuevo en python-pandas y personalmente no buscaba nada elegante o grandioso; lo que sea que funcionó estaba bien. Pero sinceramente, gracias por la solución.
melena
2

Vieja pregunta; ¡pero siempre trato de usar el código más rápido!

Tenía una lista enorme con 69 millones de uint64. np.array () fue el más rápido para mí.

df['hashes'] = hashes
Time spent: 17.034842014312744

df['hashes'] = pd.Series(hashes).values
Time spent: 17.141014337539673

df['key'] = np.array(hashes)
Time spent: 10.724546194076538
Mehdi
fuente