首页 > 解决方案 > 如何使用多处理更快地遍历列表数据?

问题描述

我正在尝试确定一系列员工在现场轮班期间的工作时间 - 这些数据以 CSV 文件的形式提供给我。从那里,我将数据放入一个矩阵中,并使用 while 循环应用必要的条件(例如,扣除 30 分钟的午餐时间)对其进行迭代。然后将其放入一个新列表中,该列表用于制作 Excel 工作表。

我的脚本做了它应该做的事情,但是在必须循环大量数据时需要很长时间(它需要循环大约 26 000 行)。我的想法是使用多处理并行执行以下三个循环:

  1. 将时间从 hh:mm:ss 转换为分钟。
  2. 循环并应用条件。
  3. 将值四舍五入并转换回小时,这样就不会在大的 while 循环中完成。

这是一个好主意吗?如果是这样,当我需要一个循环中的数据在下一个循环中使用时,我将如何让这些循环并行运行?我的第一个想法是使用时间函数来延迟,但后来我担心我的循环可能会“赶上”彼此并吐出被调用的列表索引不存在。

任何更有经验的意见将是惊人的,谢谢!

我的脚本:

import pandas as pd

功能:将时间四舍五入到下一个最小的十分钟 --> 77 = 70 ; 32 = 30:

def floor_time(n,小数=0):

multiplier = 10 ** decimals
return int(n * multiplier) / multiplier

功能:从excel电子表格中获取数据:

定义获取数据():

df = pd.read_csv('/Users/Chadd/Desktop/dd.csv', sep = ',')
list_of_rows = [list(row) for row in df.values]
data = []
i = 0
while i < len(list_of_rows):
    data.append(list_of_rows[i][0].split(';'))
    data[i].pop()
    i += 1
return data

功能:将数据中的时间索引转换为 24 小时制:

def get_time(time_data):

return int(time_data.split(':')[0])*60 + int(time_data.split(':')[1])

功能:循环通过 CSV 中的数据应用条件:

def get_time_worked():

i = 0 # Looping through entry data
j = 1 # Looping through departure data
list_of_times = []

while j < len(get_data()):

    start_time = get_time(get_data()[i][3])
    end_time = get_time(get_data()[j][3])

     # Morning shift - start time < end time
    if start_time < end_time:
        time_worked = end_time - start_time # end time - start time (minutes)
        # Need to deduct 15 minutes if late:
        if start_time > 6*60: # Late
            time_worked = time_worked - 15
        # Need to set the start time to 06:00:00:
        if start_time < 6*60: # Early
            time_worked = end_time - 6*60

    # Afternoon shift - start time > end time
    elif start_time > end_time:
        time_worked = 24*60 - start_time + end_time # 24*60 - start time + end time (minutes)
        # Need to deduct 15 minutes if late:
        if start_time > 18*60: # Late
            time_worked = time_worked - 15
        # Need to set the start time to 18:00:00:
        if start_time > 18*60: # Early
            time_worked = 24*60 - 18*60 + end_time

    # If time worked exceeds 5 hours, deduct 30 minutes for lunch:
    if time_worked >= 5*60:
        time_worked = time_worked - 30

    # Set max time worked to 11.5 hours:
    if time_worked > 11.5*60:
        time_worked = 11.5*60

    list_of_times.append([get_data()[i][1], get_data()[i][2], round(floor_time(time_worked, decimals = -1)/60, 2)])

    i += 2
    j += 2

return list_of_times

将数据保存到 Excel 工作表中:

定义保存数据():

file_heading = '{} to {}'.format(get_data()[0][2], get_data()[len(get_data())-1][2])
file_heading_2 = file_heading.replace('/', '_')

df = pd.DataFrame(get_time_worked())
writer = pd.ExcelWriter('/Users/Chadd/Desktop/{}.xlsx'.format(file_heading_2), engine='xlsxwriter')
df.to_excel(writer, sheet_name='Hours Worked', index=False)
writer.save()

保存数据()

标签: pythonexcelpandaswhile-loopmultiprocessing

解决方案


您可以查看multiprocessing.Pool哪个允许使用不同的输入变量多次执行函数。从文档

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))

然后,将数据分成块(而不是[1, 2, 3]示例中的)。
但是,我个人的偏好是花时间学习一些默认分发的东西。比如Sparkpyspark。从长远来看,它将极大地帮助您。


推荐阅读