第一个数据帧: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中的数字(即注入)乘以价格并将其放入新的数据框中,并考虑到:
我已经写了一些有用的功能:
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小时才能得到我的结果,它们甚至可能是错的。我可以处理几天运行 - 发现错误 - 运行 - 发现错误-...但不是几个月。
我确定有一种方法可以优化这个循环,获得了大量的时间(我已经设法从200h到100h)。但是,我对python / pandas / etc很新,我没有自己优化它的经验;这是一种绝望的呼唤。
答案 0 :(得分:0)
如果没有更多信息,很难写出确切的答案,但这是一次尝试。
首先,堆叠inj_2014
以将列名放入名为EAN
的新列中:
inj_stacked = inj_2014.set_index('Date') \
.stack() \
.reset_index(drop=False) \
.rename(columns={'level_1': 'EAN', 0: 'injection'})
第二次,与db
合并(价格我推荐查询):
inj_stacked = inj_stacked.merge(db, on='EAN', how='outer')
注意:您必须尝试how
的不同值。以上是我最好的猜测。
第三次,对您应用的操作进行矢量化:
inj_stacked['in_contrat'] = (inj_stacked['Date'] > inj_stacked['sd']) \
& (inj_stacked['Date'] < inj_stacked['ed'])
inj_stacked['price_name'] = inj_stacked['Date'].apply(price_name,
args=(dates_2014,))
第四,查询价格:
inj_stacked['price'] = prices.set_index('EAN').lookup(
inj_stacked['EAN'],
inj_stacked['price_name']).values
这都是未经测试的,请根据需要进行调整。