pandas 将函数应用于包含前一行数据的 Dataframe

beq87vna  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(134)

我有一个每日水果消费的输入 Dataframe ,如下所示:
spend_df

Date        Apples      Pears      Grapes     
01/01/22      10         47          0
02/01/22      0          22          3
03/01/22      11         0           3
...

对于每种水果,我需要使用它们各自的参数和输入花费来应用一个函数,该函数包括前一天和当天的花费,如下所示:
y = beta(1 - exp(-(theta*previous + current)/alpha))
parameters_df

Parameter    Apples      Pears      Grapes  
alpha         132         323        56
beta          424         31         33
theta         13          244        323

我的输出数据框应如下所示(可能包含错误):
profit_df

Date         Apples        Pears       Grapes     
01/01/22      30.93         4.19        0       
02/01/22      265.63        31.00       1.72
03/01/22      33.90         30.99       32.99
...

这是我的尝试:

# First map parameters_df to spend_df
merged_df = input_df.merge(parameters_df, on=['Apples','Pears','Grapes'])

# Apply function to each row
profit_df = merged_df.apply(lambda x: beta(1 - exp(-(theta*x[-1] + x)/alpha))
jq6vz3qz

jq6vz3qz1#

如果你先从parameters_dfspend_df中提取必要的变量,那么它可能更容易阅读,然后简单地应用这个公式就会产生预期的输出。

# extract alpha, beta, theta from parameters df
alpha, beta, theta = parameters_df.iloc[:, 1:].values
# select fruit columns
current = spend_df[['Apples', 'Pears', 'Grapes']]
# find previous values of fruit columns
previous = current.shift(fill_value=0)

# calculate profit using formula
y = beta*(1 - np.exp(-(theta*previous + current) / alpha))
profit_df = spend_df[['Date']].join(y)

gzjq41n4

gzjq41n42#

使用Pandas rolling函数的另一种方法(这是一个通用版本,可以根据需要生成尽可能多的水果):

import pandas as pd
import numpy as np

sdf = pd.DataFrame({
  "Date": ['01/01/22', '02/01/22', '03/01/22'],
  "Apples": [10, 0, 11],
  "Pears": [47, 22, 0],
  "Grapes": [0, 3, 3],  
}).set_index("Date")

pdf = pd.DataFrame({
  "Parameter": ['alpha', 'beta', 'theta'],
  "Apples": [132, 424, 13],
  "Pears": [323, 31, 244],
  "Grapes": [56, 33, 323],  
}).set_index("Parameter")

def func(r):
    t = (pdf.loc['alpha', r.name], pdf.loc['beta', r.name], pdf.loc['theta', r.name])
    return r.rolling(2).apply(lambda x: t[1]*(1 - np.exp(-(t[2]*x[0] + x[1])/t[0])))

r1 = sdf.iloc[0:2,:].shift(fill_value=0).apply(lambda r: func(r), axis=0)
r = sdf.apply(lambda r: func(r), axis=0)

r.iloc[0]=r1.shift(-1).iloc[0]

print(r)
    • 结果**
Apples      Pears     Grapes
Date                                      
01/01/22   30.934651   4.198004   0.000000
02/01/22  265.637775  31.000000   1.721338
03/01/22   33.901168  30.999998  32.999999

相关问题