我是python /编码的新手。我正在努力制作下面的代码(非常自豪)但我现在遇到性能问题 - 不知道如何解决它们。
我的任务如下: 每个产品都有交货时间和生产时间戳。生产时间可以从交货前1天15:00到交货前30分钟。我想将每个交货时间的生产时间汇总到15分钟,并在每个时间间隔内对生产单位执行几个简单的操作 (并非所有这些都是内置的功能) - 体积加权平均价格,总量(总和),标准差等。
我的问题: 数据集包含大约1100万个数据点。计算6个月的时间超过24小时。我试图遍历sql查询,只导入了15分钟的时间段,但情况更糟
我的问题: 您是否认为有任何方法可以改善此操作的性能? 这将是惊人的< 3
原始输入数据看起来像:
Column StartOfDelivery EndOfDelivery ProductionDateTime PriceEURpMW QuantityMW p*Q
73 2017-01-03 01:00:00 2017-01-03 02:00:00 2017-01-02 19:03:00 37,4 20 748
80 2017-01-03 01:00:00 2017-01-03 02:00:00 2017-01-02 19:08:00 35,9 25 897,5
86 2017-01-03 01:00:00 2017-01-03 02:00:00 2017-01-02 19:23:00 36,3 1 36,3
94 2017-01-03 01:00:00 2017-01-03 02:00:00 2017-01-02 19:24:00 35,3 0,4 14,12
915 2017-01-03 02:00:00 2017-01-03 03:00:00 2017-01-02 23:47:00 33,7 5 168,5
929 2017-01-03 02:00:00 2017-01-03 03:00:00 2017-01-02 23:50:00 32,6 0,3 9,78
340 03.01.2017 02:00:00 2017-01-03 03:00:00 2017-01-02 22:17:00 34 7,9 268,6
345 2017-01-03 02:00:00 2017-01-03 03:00:00 2017-01-02 22:19:00 34 0,8 27,2
输出数据如下所示:
index StartDelivery Production(intervall) Quantity VWAP
17 2017-01-03 01:00:00 2017-01-02 19:00:00 45 36,56666667
18 2017-01-03 01:00:00 2017-01-02 19:15:00 1,4 36,01428571
...
69 2017-01-03 02:00:00 2017-01-02 22:15:00 8,7 34
70 2017-01-03 02:00:00 2017-01-02 23:45:00 5,3 33,63773585
我的代码到目前为止:
import mysql.connector
import numpy as np
import pandas as pd
import datetime
conn=mysql.connector.connect(user='AriHeck',password='none',host='local',database='DataEvaluation', port=3308)
df = pd.read_sql("select StartOfDelivery,EndOfDelivery,ProdDateTime,PriceEURpMW,QuantityMW, PriceEURpMW*QuantityMW as 'p*Q' from `Production`\
where timestampdiff(hour,StartOfDelivery,EndOfDelivery)=1 AND StartOfDelivery >= '2017-01-03 01:00:00' AND StartOfDelivery < '2017-01-03 03:00:00'", con=conn)
#Delivery Time Loop
dt=datetime.datetime.strptime('2017-01-03 01:00:00', "%Y-%m-%d %H:%M:%S")
end_date=datetime.datetime.strptime('2017-01-05 00:00:00', "%Y-%m-%d %H:%M:%S")
#Dummies loops
incr_delivery_loop=datetime.timedelta(hours=1)
incr_production_loop=datetime.timedelta(minutes=15)
delta_start=datetime.timedelta(days=1)
delta_end=datetime.timedelta(minutes=30)
#Dummies Data
a=1
delivery_array=[0]*a
production_array=[0]*a
time_remaining_array=[0]*a
VWAP_array=np.zeros(a)
quantity_array=np.zeros(a)
#Start Delivery time loop
while (dt <= end_date):
#Production Time Loop:
#Start Production: 1 Day before delivery 15:00 (3:00 PM), End Production 30 mins before delivery
prod_time=(dt-delta_start).replace(hour=15)
end_prod=dt-delta_end
while (prod_time<=end_prod):
quantity=df[(df['StartOfDelivery']==dt)& (df['ProdDateTime']>=prod_time) & (df['ProdDateTime']<(prod_time+incr_production_loop))].QuantityMW.sum()
if (quantity==0):
VWAP=0
else:
#Calculate Volume Weighted Average Price
pq_total=df[(df['StartOfDelivery']==dt)& (df['ProdDateTime']>=prod_time) & (df['ProdDateTime']<(prod_time+incr_production_loop))]['p*Q'].sum()
VWAP=pq_total/quantity
#Save values to arrays
VWAP_array=np.append(VWAP_array,VWAP)
quantity_array=np.append(quantity_array,quantity)
delivery_array.append(dt)
production_array.append(prod_time)
#Increments
prod_time=prod_time+incr_production_loop
dt=dt+incr_delivery_loop
#END LOOPS
#Save to Dataframe
WAP_dict={'TimeOfDelivery':delivery_array,
'ProductionDateTime':production_array,
'VWAP':VWAP_array,
'Quantity':quantity_array,}
df_WAP=pd.DataFrame(WAP_dict)
df_WAP=df_WAP[['TimeOfDelivery','ProductionDateTime','Quantity','VWAP']]
#Output
print(df_WAP.head(50))
python 3.4,Windows 10,eclipse IDE
答案 0 :(得分:0)
欢迎来到python! Profiling您的代码将是一个很好的起点:)
也就是说,随着数据集的增长,每次调用都会:
df['some_column']==some_variable
变得更贵。如果您在处理2天数据时表现良好,但在扩展到6个月时表现下降,则可能是罪魁祸首。
尝试通过将order by StartOfDelivery
添加到SQL查询的末尾来对数据进行预排序。然后将数据帧拆分为数据帧列表,其中每个子帧仅包含循环体内所需的15分钟增量记录。
然后,您可以将该列表作为主循环而不是:
进行迭代while (dt <= end_date):
这应该删除所有数据帧过滤,并使您的执行时间与数据集大小成线性(ish)。