Supongamos que tengo un marco de datos de pandas como:

         Date  Type  Rate  Load
0  2017-01-02  Rain    23    10
1  2017-01-02   Dry    30    15
2  2017-01-02  Rain    32    20
....

También tengo una función de costo cost(Type, Rate) devuelve un número real.

¿Cómo puedo crear una nueva columna que para cada fila calcule la suma de Load todas las demás filas que tengan el mismo Date y que tengan menos cost() de esa fila dada?

Por ejemplo, si la función de costo es simplemente:

def cost(Type, Rate):
    if Type=='Rain':
        return Rate/12
    else:
        return Rate/17

La salida será:

         Date  Type  Rate  Load  Output
0  2017-01-02  Rain    23    10   15           
1  2017-01-02   Dry    30    15   0          
2  2017-01-02  Rain    32    20   15+10=25    
....

Actualizar. La forma actual en la que estoy pensando es crear una nueva columna que calcule el cost de cada fila primero, y en el siguiente paso, cree una nueva columna que resuma todos los registros para cada fila que tiene la misma fecha y teniendo el menor costo. Pero, ¿hay alguna forma más rápida de combinar ambos?

1
Mohammad Hosein Eshraghi 24 jun. 2020 a las 01:06

2 respuestas

Puedes probar esto con df.to_records():

print(df)
cost= lambda Type, Rate:  Rate/12 if Type=='Rain' else Rate/17

l=[sum([j[4] for j in df.to_records() if list(j)[1]==list(i)[1] and list(i)!=list(j) and cost(list(j)[2],list(j)[3])<cost(list(i)[2],list(i)[3])]) for i in df.to_records()]
df['Output']=l
print(df)

Salida:

df:
        Date  Type  Rate  Load
0 2017-01-01  Rain    23    10
1 2017-01-01   Dry    22    10
2 2017-01-01  Rain    25    10
3 2017-01-02   Dry    30    15
4 2017-01-02  Rain    32    20

df with output column:
        Date  Type  Rate  Load  Output
0 2017-01-01  Rain    23    10      10
1 2017-01-01   Dry    22    10       0
2 2017-01-01  Rain    25    10      20
3 2017-01-02   Dry    30    15       0
4 2017-01-02  Rain    32    20      15
0
MrNobody33 23 jun. 2020 a las 23:10
row_sum = df.groupby(["Date"]).sum()
costs = [row_sum[row_sum["Date"] == i["Date"]] - cost(i["Type"], i["Rate"]) for i in df.iterrows()])

df["Output"] = costs

0
Victor Silva 23 jun. 2020 a las 22:24