pandas numpy: cómo simplificar múltiples parámetros de funciones vectorizadas
Tengo un df, lo puedes obtener al ejecutar este código:
import numpy as np
import pandas as pd
from io import StringIO
dfs = """
M0 M1 M2 M3 M4 M5 age
1 1 2 3 4 5 6 3.2
2 7 5 4 5 8 3 4.5
3 4 8 9 3 5 2 6.7
"""
df = pd.read_csv(StringIO(dfs.strip()), sep='\s+', )
Y en base a la lógica del negocio, tengo la siguiente función, la salida también es lo que esperaba:
def func(M0,M1,M2,M3,M4,M5,age):
newcol=np.prod([M0,M1,M2,M3,M4,M5][0:age])
return newcol
vfunc = np.frompyfunc(func, 7, 1)
df['newcol']=vfunc(df['M0'].values,df['M1'].values,df['M2'].values,df['M3'].values,df['M4'].values,df['M5'].values,df['age'].values.astype(int))
df
La salida es:
M0 M1 M2 M3 M4 M5 age newcol
1 1 2 3 4 5 6 3.2 6
2 7 5 4 5 8 3 4.5 700
3 4 8 9 3 5 2 6.7 8640
El problema es que hay demasiados parámetros en def func(M0,M1,M2,M3,M4,M5,age)
, ¿hay alguna manera de hacer que estos parámetros sean una lista o algo más para que la función sea más limpia?
Intenté lo siguiente:
def func(df):
newcol=np.prod([df['M0'].values,df['M1'].values,df['M2'].values,df['M3'].values,df['M4'].values,df['M5'].values][0:df['age'].values.astype(int)])
return newcol
vfunc = np.frompyfunc(func,1, 1)
df['newcol']=vfunc(df)
Pero tengo un error:
TypeError: 'float' object is not subscriptable
Observar la razón por la que no utilizo pd.apply()
, es porque en mi negocio real, los datos son muy grandes y pd.apply()
se ejecuta muy lentamente.
davy.ai
Sí, puedes crear una lista o un arreglo de numpy a partir de los valores de entrada y pasarlos como un solo argumento a la función. Aquí hay un ejemplo:
En este código, la fila de entrada se pasa como un solo argumento a la función
func
. La primera línea extrae todas las columnas excepto la última (que se asume es la columna deedad
) y las convierte en un arreglo numpy. La segunda línea extrae la columna deedad
y la convierte en un entero. Luego, la función calcula la salida deseada y la devuelve.También puedes usar
df.values
para obtener un arreglo de numpy 2D con todos los valores de entrada:Este código es similar al anterior, pero usa
df.values
para obtener un arreglo de numpy 2D con todos los valores de entrada en lugar de pasar una fila como un argumento separado a la función. La funciónvfunc
luego aplica la funciónfunc
elemento por elemento a este arreglo, calculando la salida para cada fila. Es importante destacar quenp.vectorize
no es tan eficiente como usarapply
o un bucle, pero puede ser útil en algunos casos en los que necesitas aplicar una función personalizada a un arreglo de numpy.