Python pandas cómo usar una función con math, usar apply y lambda
Tengo una parte de programa con el siguiente dataframe de ejemplo:
import pandas as pd
from math import floor
d = {'ind': ['a', 'b', 'c'], 'col1': [1, 2, 3], 'col2': [4, 5, 6], 'col3': [7, 8, 9], 'spec': [9, 6, 3]}
df = pd.DataFrame(data=d).set_index('ind')
def func(x, y):
return (1-x)*(y+1)*0.9
print(df)
df2 = df.apply(lambda x: func(x, df.spec))
print(df2)
Funciona bien, pero cuando modifico un poco la función y le agrego floor
:
def func(x, y):
return floor((1-x)*(y+1)*0.9)
Obtengo el siguiente error:
TypeError: cannot convert the series to <class 'float'="">
¿Cómo puedo cambiar df2
o func
para que funcione?
EDICIÓN DESPUÉS DE UNA BUENA RESPUESTA:
Ahora veo que olvidé que tengo una condición en la función, y necesito algo más para que funcione.
def func(x, y):
if x == 1:
return y
else:
return floor((1-x)*(y+1)*0.9)
Con esta función y las respuestas que recibí, obtengo:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Señala la línea if x == 1:
.
davy.ai
El problema es que la función
floor
no se puede aplicar directamente a una serie de datos. Una solución para esto es usar el métodoapplymap
del objeto DataFrame para aplicar la función elemento a elemento a cada celda:Esto aplicará la función
floor
a cada celda del DataFramedf2
, que contiene la salida de la funciónfunc
. El métodoapplymap
aplica una función elemento a elemento a cada celda del DataFrame, lo cual resuelve el problema de aplicar la funciónfloor
a una serie de datos.Sin embargo, ten en cuenta que esta solución solo funcionará si la función
func
es capaz de devolver un valor flotante para cada celda. Si la función devuelve un valor booleano o una cadena de texto para algunas celdas, podrías encontrarte con problemas.