我试图提高当前代码的性能,从而循环遍历一个数据框(数据框“ 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})
为了获得更好的速度,我将两个DataFrames中的索引都设置为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倍。
自行检查。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句