python - 如何使用多处理更快地遍历列表数据?
问题描述
我正在尝试确定一系列员工在现场轮班期间的工作时间 - 这些数据以 CSV 文件的形式提供给我。从那里,我将数据放入一个矩阵中,并使用 while 循环应用必要的条件(例如,扣除 30 分钟的午餐时间)对其进行迭代。然后将其放入一个新列表中,该列表用于制作 Excel 工作表。
我的脚本做了它应该做的事情,但是在必须循环大量数据时需要很长时间(它需要循环大约 26 000 行)。我的想法是使用多处理并行执行以下三个循环:
- 将时间从 hh:mm:ss 转换为分钟。
- 循环并应用条件。
- 将值四舍五入并转换回小时,这样就不会在大的 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()
保存数据()
解决方案
您可以查看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]
示例中的)。
但是,我个人的偏好是花时间学习一些默认分发的东西。比如Spark
和pyspark
。从长远来看,它将极大地帮助您。
推荐阅读
- python - 在本地 linux 机器和谷歌 colab 上 gpu 使用 tensorflow 的差异
- python - 在 Google Cloud Functions 中安装具有依赖项的软件包
- django - 调试时没有为 Django 显示表格
- kubernetes - 如何将 statefulset 的第一个副本调度到特定节点
- iphone - 从 Xcode 加载应用程序时,iPhone 存储中的应用程序文档和数据不断增加
- validation - 如何在从“05”开始的 woocommerce 结帐页面中创建验证电话号码
- reactjs - 在 FullCalendar 中自定义 Day Cell 内容
- php - 插入在特定类别页面的标题下
- spring - JPA - 变量 double 正在四舍五入
- google-bigquery - 在 bigquery 中将数组 ['a','b'] 转换为字符串 ('a','b')