Python脚本|长期运行需要建议以进行优化

时间:2019-02-15 19:59:55

标签: python-2.7

我已经写了这个脚本来生成一个数据集,该数据集将基于365天一周中所有天的营业时间提供的输入来包含15分钟的时间间隔。

示例:假设商店1 在全天的上午9点开放,并在晚上9点关闭。每天12个小时。 12 * 4 = 48(每天15分钟)。 48 * 365 = 17520(一年15分钟)。

样本数据集仅包含5个站点,但是此脚本需要为其生成数据的大约9000个站点。

该脚本显然可以在少数站点(100)和几天(2)上运行,但需要在站点(9000)和365天上运行。

正在寻找建议,以加快运行速度。这将在本地计算机上运行。

输入数据:https://drive.google.com/open?id=1uLYRUsJ2vM-TIGPvt5RhHDhTq3vr4V2y

输出数据:https://drive.google.com/open?id=13MZCQXfVDLBLFbbmmVagIJtm6LFDOk_T

请让我知道是否可以提供其他帮助以得到答案。

def datetime_range(start, end, delta):
current = start
while current < end:
    yield current
    current += delta

import pandas as pd
import numpy as np
import cProfile
from datetime import timedelta, date, datetime

#inputs
empty_data = pd.DataFrame(columns=['store','timestamp'])
start_dt = date(2019, 1, 1)
days = 365

data = "input data | attached to the post"
for i in range(days):
for j in range(len(data.store)):
curr_date = start_dt + timedelta(days=i)  
curr_date_year = curr_date.year
curr_date_month = curr_date.month
curr_date_day =  curr_date.day
weekno = curr_date.weekday()
if weekno<5:
  dts = [dt.strftime('%Y-%m-%d %H:%M') for dt in 
  datetime_range(datetime(curr_date_year,curr_date_month,curr_date_day,data['m_f_open_hrs'].iloc[j],data['m_f_open_min'].iloc[j]), datetime(curr_date_year,curr_date_month,curr_date_day, data['m_f_close_hrs'].iloc[j],data['m_f_close_min'].iloc[j]), 
  timedelta(minutes=15))]
  vert = pd.DataFrame(dts,columns = ['timestamp']) 
  vert['store']= data['store'].iloc[j]
  empty_data = pd.concat([vert, empty_data])
elif weekno==5:
  dts = [dt.strftime('%Y-%m-%d %H:%M') for dt in 
  datetime_range(datetime(curr_date_year,curr_date_month,curr_date_day,data['sat_open_hrs'].iloc[j],data['sat_open_min'].iloc[j]), datetime(curr_date_year,curr_date_month,curr_date_day, data['sat_close_hrs'].iloc[j],data['sat_close_min'].iloc[j]), 
  timedelta(minutes=15))]
  vert = pd.DataFrame(dts,columns = ['timestamp'])
  vert['store']= data['store'].iloc[j]
  empty_data = pd.concat([vert, empty_data])
else:
  dts = [dt.strftime('%Y-%m-%d %H:%M') for dt in 
  datetime_range(datetime(curr_date_year,curr_date_month,curr_date_day,data['sun_open_hrs'].iloc[j],data['sun_open_min'].iloc[j]), datetime(curr_date_year,curr_date_month,curr_date_day, data['sun_close_hrs'].iloc[j],data['sun_close_min'].iloc[j]), 
  timedelta(minutes=15))]
  vert = pd.DataFrame(dts,columns = ['timestamp'])
  vert['store']= data['store'].iloc[j]
  empty_data = pd.concat([vert, empty_data])


final_data = empty_data

1 个答案:

答案 0 :(得分:0)

我认为脚本中最耗时的任务是日期时间计算。

您应该尝试使用UNIX Time进行所有这些计算。它基本上将时间表示为一个数秒的整数...因此您可以获取两个UNIX日期,只需进行简单的减法即可了解两者之间的差异。

我认为您应该执行所有类似的操作...,并且在该过程完成后,您可以将所有日期时间转换为更具可读性的日期格式。

您应该在脚本中更改的另一件事是几乎相同的所有代码重复。它不会提高性能,但是会提高可读性,调试和程序员的技能。作为一个简单的示例,我重构了一些代码(您可能比我做的要好,但这只是一个示例)。

def datetime_range(start, end, delta):
    current = start
    while current < end:
        yield current
        current += delta

from datetime import timedelta, date, datetime
import numpy as np
import cProfile
import pandas as pd

# inputs
empty_data = pd.DataFrame(columns=['store', 'timestamp'])
start_dt = date(2019, 1, 1)
days = 365

data = "input data | attached to the post"
for i in range(days):
    for j in range(len(data.store)):
        curr_date = start_dt + timedelta(days=i)
        curr_date_year = curr_date.year
        curr_date_month = curr_date.month
        curr_date_day = curr_date.day

        weekno = curr_date.weekday()

        week_range = 'sun'
        if weekno < 5:
            week_range = 'm_f'
        elif weekno == 5:
            week_range = 'sat'

        first_time = datetime(curr_date_year,curr_date_month,curr_date_day,data[week_range + '_open_hrs'].iloc[j],data[week_range + '_open_min'].iloc[j])
        second_time = datetime(curr_date_year,curr_date_month,curr_date_day, data[week_range + '_close_hrs'].iloc[j],data[week_range + '_close_min'].iloc[j])
        dts = [ dt.strftime('%Y-%m-%d %H:%M') for dt in datetime_range(first_time, second_time, timedelta(minutes=15)) ]

        vert = pd.DataFrame(dts, columns = ['timestamp'])
        vert['store']= data['store'].iloc[j]
        empty_data = pd.concat([vert, empty_data])

final_data = empty_data

祝你好运!