【发布时间】:2017-04-25 03:06:03
【问题描述】:
第一个数据帧:inj_2014 (35040, 991),其中列引用对应于所谓的 EAN。
Date 541448860005060119 541448860003851078 ...
0 2014-01-01 00:00:00 0.0 0.0
1 2014-01-01 00:15:00 0.1 0.0
...
第二个数据帧:db (1125,17)。在这里,EAN 被重新组合在一列中。行数比 991 多,因为它对应于合同规范:如果合同在 2014 年 2 月结束并在 2014 年 3 月再次开始,则 df 中有 2 行。 sd 和 ed 列分别对应开始日期和结束日期
EAN sd ed ...
0 541448860008422181 2014-07-02 2017-01-03
1 541449200002077458 2012-01-04 2014-05-07
...
第三个数据框:价格 (1125,9)。基本上每个 EAN 都有不同的价格规格,全年(Q1-Q2-Q3-Q4)和时间(高峰-非高峰)变化
Q1_peak Q1_off_peak ... Q4_off_peak EAN
0 82.0264 56.9196 61.9826 541448860008422181
1 85.2736 57,8456 58,7564 541449200002077458
...
我想要做的:将inj_2014中的数字(即注入)乘以价格并将其放入新的数据框中,考虑到:
- 如果日期不在合同范围内(或返回0),则不应计算注入的事实
- 事实上 2 个不同的合同可能具有相同的 EAN,因此应该输出 2 个不同的列(例如,EAN_1 表示最近的合同)
- 注入的价格应乘以取决于日期和 EAN 的事实
我已经写了一些有用的函数:
def in_contrat(date, sd, ed):
'''True if date within date limits'''
if sd < date < ed:
return True
else:
return False
def price_name(date, dates_2014): #dates_2014 = list of the quarter limit dates
'''returns price name corresponding to the given date'''
if date < date_2014[1]:
if peak(date):
return 'Q1_peak'
else:
return 'Q1_off_peak'
elif date < date_2014[2]:
if peak(date):
return 'Q2_peak'
...
def in_contrat(date, sd, ed):
'''True if date within date limits'''
if sd < date < ed:
return True
else:
return False
def get_index(df, test):
'''returns list with index occurences of the specific EAN number in the db'''
index = []
for i in range(len(df)):
if df['EAN'][i] == test:
index.append(i)
return index
所以我尝试用这个材料编写我的主函数:
def daily_calculation(inj_2014, db, prices):
list_EAN = []
for i in range(len(db)):
EAN = db['EAN'][i]
if EAN not in list_EAN:
list_EAN.append(EAN)
index = get_index(prices, EAN)[0]
else :
index = get_index(prices, EAN)[1]
for j in range(len(inj_2014)):
date = inj_2014['Date'][j]
name = price_name(date, dates_2014)
EBIQ = prices[name][index]
valeur_injection = inj_2014[EAN][j]/4000
if in_contrat(date, db['sd'][i], db['ed'][i]) and inj_2014[EAN][j] != 0:
results.set_value(j, EAN, (valeur_injection)*EBIQ)
else:
results.set_value(j, EAN, 0)
return results
所以问题是,这似乎有效。然而,考虑到我只计算第一列所花费的时间,我应该需要 80 到 100 小时才能得到我的结果,甚至可能是错误的。我可以处理几天运行-查找错误-运行-查找错误-...但不是几个月。
我确信有一种方法可以优化这个循环,从而获得大量时间(我已经设法从 200 小时缩短到 100 小时)。但是,我对 python/pandas/etc 还是很陌生,我没有自己优化它的经验;这是一种绝望的呼唤。
【问题讨论】:
标签: python performance loops pandas optimization