python性能(1):multiprocessing多进程

这个系列放涉及Python性能相关的处理,总的来说-除了优化代码逻辑和数据结构,其他的就是增加计算或存储资源、时间换空间、空间换时间。首先,较常用的,处理大量数据时通过多进程利用CPU的多核可以并行处理从而达到加速运算的目的,此处初步小结python内置模块multiprecessing的简单使用。

进程的知识点不少,方法也好多类,这里先放一个

Pool.map

目前我用的最多的简单粗暴的并行

有大堆数据,需要进行相同的处理(函数)

1
2
from multiprocessing import cpu_count
print(cpu_count())

上面的函数查看电脑CPU的核数/即最大并行进程数

1
2
3
4
5
6
7
8
9
10
11
from multiprocessing import Pool
# 也可以定义全局参数用于函数内
root = "..."
def f(file):
# 这里定义处理的函数
pass
# 8代表八个进程即使用8个核
if __name__ == '__main__':
pool = Pool(8)
# files是一个参数列表list,[file1, file2, ...]
pool.map(f, files)

该函数只适用于单个单数,对于多个参数,如果有多个参数,则可以将参数用元组封装传参后再拆包,如下示例:

  • paras是一个列表,每个元素都是一个函数f的输入参数
  • 对于固定参数如路径path等,则可以定义全局参数放在开始或者放在函数内部
  • 可自行构造参数的列表,可使用列表运算符,或结合range函数实现
    • 数量增加*a = [1,2,3]; b = a*2; b = [1,2,3,1,2,3]

也可以使用starmap(),多参数以及pandas遍历用法参见这个笔记

1
2
3
4
5
6
7
8
9
10
11
path = r"A:\Data"
def f(paras):
file, date = paras
savefile = path+"\\"+str(date)+".csv"
...
if __name__ == '__main__':
pool = Pool(8)
files = glob(r"A:\Data\indata\*.txt")
# 此处我通过循环构造参数列表,days和files数量相同
paras = [(file, day) for file in files for date in dates]
pool.map(f,paras)

常用自定义函数

常用辅助函数,很多时候需要根据处理的文件自动创建文件夹,比如:

  • 这里我经常用到的一个dataframe按列拆分并运算,然后输出的函数
1
2
3
4
5
6
7
8
9
10
11
12
def create_dir(cwd):
isExists = os.path.exists(cwd)
if not isExists:
os.makedirs(cwd)
return cwd

# 这也是很常用的一个df拆分函数
for year,table in df.groupby('year'):
outdir = create_dir(dir+"\\"+str(year))
...
outfile = outdir+...+".csv"
table.to_csv(..., encoding = 'utf-8', index=False)