首页 > 解决方案 > 如何在python中将多个if else循环转换为列表理解

问题描述

我正在使用以下 if 循环来为大约 100 万次观察创建半小时的存储桶,这需要花费大量时间。以下是我的 if 循环

def half_hourly_buckets(dataframe,time_column):
   dataframe[time_column] = pd.to_datetime(dataframe[time_column],format = '%H:%M:%S').dt.time
   for j in range(len(dataframe)):
    x = dataframe.loc[j,time_column]
    if (x >= datetime.time(0,0,1)) & (x <= datetime.time(0,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "00:00:01 - 00:30:00"
    elif (x >= datetime.time(0,30,1)) & (x <= datetime.time(1,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "00:30:01 - 01:00:00"
    elif (x >= datetime.time(1,0,1)) & (x <= datetime.time(1,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "01:00:01 - 01:30:00"
    elif (x >= datetime.time(1,30,1)) & (x <= datetime.time(2,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "01:30:01 - 02:00:00"
    elif (x >= datetime.time(2,0,1)) & (x <= datetime.time(2,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "02:00:01 - 02:30:00"
    elif (x >= datetime.time(2,30,1)) & (x <= datetime.time(3,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "02:30:01 - 03:00:00"
    elif (x >= datetime.time(3,0,1)) & (x <= datetime.time(3,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "03:00:01 - 03:30:00"
    elif (x >= datetime.time(3,30,1)) & (x <= datetime.time(4,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "03:30:01 - 04:00:00"
    elif (x >= datetime.time(4,0,1)) & (x <= datetime.time(4,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "04:00:01 - 04:30:00"
    elif (x >= datetime.time(4,30,1)) & (x <= datetime.time(5,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "04:30:01 - 05:00:00"
    elif (x >= datetime.time(5,0,1)) & (x <= datetime.time(5,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "05:00:01 - 05:30:00"
    elif (x >= datetime.time(5,30,1)) & (x <= datetime.time(6,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "05:30:01 - 06:00:00"
    elif (x >= datetime.time(6,0,1)) & (x <= datetime.time(6,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "06:00:01 - 06:30:00"
    elif (x >= datetime.time(6,30,1)) & (x <= datetime.time(7,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "06:30:01 - 07:00:00"
    elif (x >= datetime.time(7,0,1)) & (x <= datetime.time(7,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "07:00:01 - 07:30:00"
    elif (x >= datetime.time(7,30,1)) & (x <= datetime.time(8,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "07:30:01 - 08:00:00"
    elif (x >= datetime.time(8,0,1)) & (x <= datetime.time(8,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "08:00:01 - 08:30:00"
    elif (x >= datetime.time(8,30,1)) & (x <= datetime.time(9,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "08:30:01 - 09:00:00"
    elif (x >= datetime.time(9,0,1)) & (x <= datetime.time(9,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "09:00:01 - 09:30:00"
    elif (x >= datetime.time(9,30,1)) & (x <= datetime.time(10,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "09:30:01 - 10:00:00"
    elif (x >= datetime.time(10,0,1)) & (x <= datetime.time(10,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "10:00:01 - 10:30:00"
    elif (x >= datetime.time(10,30,1)) & (x <= datetime.time(11,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "10:30:01 - 11:00:00"
    elif (x >= datetime.time(11,0,1)) & (x <= datetime.time(11,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "11:00:01 - 11:30:00"
    elif (x >= datetime.time(11,30,1)) & (x <= datetime.time(12,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "11:30:01 - 12:00:00"
    elif (x >= datetime.time(12,0,1)) & (x <= datetime.time(12,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "12:00:01 - 12:30:00"
    elif (x >= datetime.time(12,30,1)) & (x <= datetime.time(13,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "12:30:01 - 13:00:00"
    elif (x >= datetime.time(13,0,1)) & (x <= datetime.time(13,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "13:00:01 - 13:30:00"
    elif (x >= datetime.time(13,30,1)) & (x <= datetime.time(14,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "13:30:01 - 14:00:00"
    elif (x >= datetime.time(14,0,1)) & (x <= datetime.time(14,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "14:00:01 - 14:30:00"
    elif (x >= datetime.time(14,30,1)) & (x <= datetime.time(15,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "14:30:01 - 15:00:00"
    elif (x >= datetime.time(15,0,1)) & (x <= datetime.time(15,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "15:00:01 - 15:30:00"
    elif (x >= datetime.time(15,30,1)) & (x <= datetime.time(16,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "15:30:01 - 16:00:00"
    elif (x >= datetime.time(16,0,1)) & (x <= datetime.time(16,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "16:00:01 - 16:30:00"
    elif (x >= datetime.time(16,30,1)) & (x <= datetime.time(17,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "16:30:01 - 17:00:00"
    elif (x >= datetime.time(17,0,1)) & (x <= datetime.time(17,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "17:00:01 - 17:30:00"
    elif (x >= datetime.time(17,30,1)) & (x <= datetime.time(18,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "17:30:01 - 18:00:00"
    elif (x >= datetime.time(18,0,1)) & (x <= datetime.time(18,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "18:00:01 - 18:30:00"
    elif (x >= datetime.time(18,30,1)) & (x <= datetime.time(19,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "18:30:01 - 19:00:00"
    elif (x >= datetime.time(19,0,1)) & (x <= datetime.time(19,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "19:00:01 - 19:30:00"
    elif (x >= datetime.time(19,30,1)) & (x <= datetime.time(20,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "19:30:01 - 20:00:00"
    elif (x >= datetime.time(20,0,1)) & (x <= datetime.time(20,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "20:00:01 - 20:30:00"
    elif (x >= datetime.time(20,30,1)) & (x <= datetime.time(21,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "20:30:01 - 21:00:00"
    elif (x >= datetime.time(21,0,1)) & (x <= datetime.time(21,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "21:00:01 - 21:30:00"
    elif (x >= datetime.time(21,30,1)) & (x <= datetime.time(22,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "21:30:01 - 22:00:00"
    elif (x >= datetime.time(22,0,1)) & (x <= datetime.time(22,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "22:00:01 - 22:30:00"
    elif (x >= datetime.time(22,30,1)) & (x <= datetime.time(23,0,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "22:30:01 - 23:00:00"
    elif (x >= datetime.time(23,0,1)) & (x <= datetime.time(23,30,0)):
        dataframe.loc[j,'half_hourly_bucket'] = "23:00:01 - 23:30:00"
    else:
        dataframe.loc[j,'half_hourly_bucket'] = "23:30:01 - 00:00:00"
return dataframe

有什么办法可以避免这个循环并提高处理速度?

标签: pythonpandas

解决方案


首先,您进行的比较次数大约是这种方法所需的两倍。如果你没有通过第一次测试,你就已经知道了

x >= datetime.time(0,30,1))

所以你不必在 next 上再次测试这个elif

其次,由于您使用的是常规存储桶,您可以通过计算秒数并使用除以三十分钟的结果的整数部分来计算出您需要哪个存储桶。假设x是一个时间对象,您可以执行以下操作:

bucket_number = int((datetime.datetime.combine(datetime.date.min, x) -
                     datetime.datetime.combine(datetime.date.min, datetime.time(0))
                    ).total_seconds() / (30 * 60))
bucket_start = datetime.datetime.combine(datetime.date.min, datetime.time(0)) + \
               datetime.timedelta(seconds = bucket_number * 30 * 60)
bucket_end = datetime.datetime.combine(datetime.date.min, datetime.time(0)) + \
             datetime.timedelta(seconds = (bucket_number + 1) * 30 * 60)
dataframe.loc[j,'half_hourly_bucket'] = "{} - {}".format(bucket_start.strftime('%H:%M:%S'),
                                                         bucket_end.strftime('%H:%M:%S'))

这将消除对任何测试的需要。

注意:这里有很多艰苦的工作是因为很难处理time对象。如果您可以改用datetime对象,这将容易得多。


推荐阅读