Estoy trabajando con la biblioteca de pandas y quiero agregar dos columnas nuevas a un marco de datos df
con n columnas (n> 0).
Estas nuevas columnas son el resultado de la aplicación de una función a una de las columnas del marco de datos.
La función a aplicar es como:
def calculate(x):
...operate...
return z, y
Un método para crear una nueva columna para una función que devuelve solo un valor es:
df['new_col']) = df['column_A'].map(a_function)
Entonces, lo que quiero, y lo intenté sin éxito (*), es algo como:
(df['new_col_zetas'], df['new_col_ys']) = df['column_A'].map(calculate)
¿Cuál podría ser la mejor manera de lograr esto? Escaneé la documentación sin ninguna pista.
** df['column_A'].map(calculate)
devuelve una serie de pandas, cada elemento que consta de una tupla z, y. Y tratar de asignar esto a dos columnas de marco de datos produce un ValueError. *
La respuesta principal es defectuosa en mi opinión. Con suerte, nadie está importando en masa todos los pandas en su espacio de nombres con
from pandas import *
. Además, elmap
método debe reservarse para esos momentos en los que se le pasa un diccionario o una Serie. Puede tomar una función, pero para esoapply
se usa.Entonces, si debe usar el enfoque anterior, lo escribiría así
En realidad, no hay razón para usar zip aquí. Simplemente puede hacer esto:
Este segundo método también es mucho más rápido en DataFrames más grandes
DataFrame creado con 300.000 filas
60 veces más rápido que zip
En general, evite usar aplicar
Aplicar generalmente no es mucho más rápido que iterar sobre una lista de Python. Probemos el rendimiento de un bucle for para hacer lo mismo que el anterior
Entonces, esto es dos veces más lento, lo que no es una regresión de rendimiento terrible, pero si citonizamos lo anterior, obtenemos un rendimiento mucho mejor. Suponiendo que está usando ipython:
Asignación directa sin aplicar
Puede obtener mejoras de velocidad aún mayores si utiliza las operaciones vectorizadas directas.
Esto aprovecha las operaciones vectorizadas extremadamente rápidas de NumPy en lugar de nuestros bucles. Ahora tenemos una aceleración 30 veces superior al original.
La prueba de velocidad más sencilla con
apply
El ejemplo anterior debería mostrar claramente lo lento que
apply
puede ser, pero para que sea más claro, veamos el ejemplo más básico. Cuadremos una serie de 10 millones de números con y sin aplicarSin aplicar es 50 veces más rápido
fuente
applymap
para el caso en el que tiene que implementar una función específica para cada elemento del marco de datos?func(series)
lugar deseries.apply(func)
solo es aplicable cuando la función está completamente definida mediante operaciones que se comportan de manera similar tanto en un valor individual como en una Serie. Ese es el caso en el ejemplo de la primera respuesta, pero no es el caso en la pregunta del OP, que pregunta de manera más general sobre la aplicación de funciones a las columnas. 1/2DataFrame({'a': ['Aaron', 'Bert', 'Christopher'], 'b': ['Bold', 'Courageous', 'Distrusted']})
ycalc
es:def calc(x): return x[0], len(x)
entoncestdf.a.apply(calc))
ycalc(tdf.a)
devuelve cosas muy diferentes.