对于数据量较大的文件,对里面的数据执行某一种相同操作时,可以考虑多进程+islice结合,利用类似“map+reduce”的思路快速输出结果
- 初始化进程池
*args传入do_analysis的参数,传入p_id及cpu数量,为后续切片使用
cpu_n = min(os.cpu_count() - 2, 10)
executor = ProcessPoolExecutor(max_workers=cpu_n)
pdata = []
for i in range(cpu_n):
pdata.append((i,cpu_n,h,infile,tmppath))
for _ in executor.map(do_analysis, pdata):
pass
- 核心处理函数
process_id,cpu_n,h,infile,bpath = args
reader = read_csv(infile) # 返回一个迭代器
# 步长相同,起点不同且连续所以可以批量差分处理
for g in read_by_trunk(islice(reader,process_id,None,cpu_n),10000)
islice
itertools.islice(iterable, stop)
itertools.islice(iterable, start, stop[, step])
iterable:可迭代对象,比如string,list,tuple…… start:开始位置 stop:结束位置 step:步长 解析:
创建一个迭代器,从迭代中返回所选元素。 如果start为非零,则跳过iterable中的元素,直到达到start。
之后,连续返回元素,除非将step设置为高于导致跳过项目的步骤。
如果stop为None,则迭代继续,直到迭代器耗尽,如果有的话;否则,它停在指定位置。
与常规切片不同,islice()不支持start,stop或step的负值。
可用于从内部结构已展平的数据中提取相关字段(例如,多行报表可在每第三行列出名称字段)。
- 文件合并(reduce)
把上面输出路径中的结果合并再删除临时文件夹即可