我正在尝试提高当前代码段的性能,由此循环遍历一个数据帧(数据帧“r”)并根据条件从另一个数据帧(数据帧“p”)中找到平均值。
我想从数据帧“p”中找到所有值(“Val”列)的平均值,其中 (r.RefDate = p.RefDate) & (r.Item = p.Item) & (p.StartDate >= r.StartDate) & (p.EndDate <= r.EndDate)
可以按照以下方式生成此虚拟数据;
import pandas as pd
import numpy as np
from datetime import datetime
######### START CREATION OF DUMMY DATA ##########
rng = pd.date_range('2019-01-01', '2019-10-28')
daily_range = pd.date_range('2019-01-01','2019-12-31')
p = pd.DataFrame(columns=['RefDate','Item','StartDate','EndDate','Val'])
for item in ['A','B','C','D']:
for date in daily_range:
daily_p = pd.DataFrame({ 'RefDate': rng,
'Item':item,
'StartDate':date,
'EndDate':date,
'Val' : np.random.randint(0,100,len(rng))})
p = p.append(daily_p)
r = pd.DataFrame(columns=['RefDate','Item','PeriodStartDate','PeriodEndDate','AvgVal'])
for item in ['A','B','C','D']:
r1 = pd.DataFrame({ 'RefDate': rng,
'Item':item,
'PeriodStartDate':'2019-10-25',
'PeriodEndDate':'2019-10-31',#datetime(2019,10,31),
'AvgVal' : 0})
r = r.append(r1)
r.reset_index(drop=True,inplace=True)
######### END CREATION OF DUMMY DATA ##########
我目前正在计算并希望提高性能的一段代码如下
for i in r.index:
avg_price = p['Val'].loc[((p['StartDate'] >= r.loc[i]['PeriodStartDate']) &
(p['EndDate'] <= r.loc[i]['PeriodEndDate']) &
(p['RefDate'] == r.loc[i]['RefDate']) &
(p['Item'] == r.loc[i]['Item']))].mean()
r['AvgVal'].loc[i] = avg_price
最佳答案
第一个变化是生成r DataFrame,PeriodStartDate 和 PeriodEndDate 创建为 datetime,请参阅以下片段 启动代码,由我更改:
r1 = pd.DataFrame({'RefDate': rng, 'Item':item,
'PeriodStartDate': pd.to_datetime('2019-10-25'),
'PeriodEndDate': pd.to_datetime('2019-10-31'), 'AvgVal': 0})
为了获得更快的速度,我将两个 DataFrame 中的索引设置为 RefDate 和 Item (两列比较相等)并按索引排序:
p.set_index(['RefDate', 'Item'], inplace=True)
p.sort_index(inplace=True)
r.set_index(['RefDate', 'Item'], inplace=True)
r.sort_index(inplace=True)
这样,通过索引访问会明显更快。
然后我定义了以下函数来计算行的平均值 来自 p 来自 r 的当前行“相关”:
def myMean(row):
pp = p.loc[row.name]
return pp[pp.StartDate.ge(row.PeriodStartDate) &
pp.EndDate.le(row.PeriodEndDate)].Val.mean()
唯一要做的就是应用这个函数(到 r 中的每一行)并且 将结果保存在 AvgVal 中:
r.AvgVal = r.apply(myMean2, axis=1)
使用 %timeit,我将 EdH 提出的代码的执行时间与我的进行了比较 得到的结果几乎缩短了 10 倍。
自行检查。
关于python - 如何提高 python 数据帧中平均计算的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58645436/