Python提高运行速度工具之Pandarallel的使用教程
作者:我爱Python数据挖掘 发布时间:2021-07-16 20:14:09
众所周知,由于 GIL 的存在,Python 单进程中的所有操作都是在一个CPU核上进行的,所以为了提高运行速度,我们一般会采用多进程的方式。而多进程无非就是以下几种方案:
multiprocessing
concurrent.futures.ProcessPoolExecutor()
joblib
ppserver
celery
这些方案对于普通 python 玩家来说都不是特别友好,怎样才能算作一个友好的并行处理方案?
那就是原来的逻辑我基本不用变,仅修改需要计算的那行就能完成我们目标的方案,而 pandarallel 就是一个这样友好的工具。
可以看到,在 pandarallel 的世界里,你只需要替换原有的 pandas 处理语句就能实现多CPU并行计算。非常方便、非常nice.
在4核CPU的性能测试上,它比原始语句快了接近4倍。测试条件(OS: Linux Ubuntu 16.04,Hardware: Intel Core i7 @ 3.40 GHz - 4 cores),这就是我所说的,它把CPU充分利用了起来。
下面就给大家介绍这个模块怎么用,其实非常简单,任何代码只需要加几行代码就能实现质的飞跃。
1.准备
开始之前,你要确保Python和pip已经成功安装在电脑上
pip install pandarallel
2.使用 Pandarallel
使用前,需要对Pandarallel进行初始化:
from pandarallel import pandarallel
pandarallel.initialize()
这样才能调用并行计算的API,不过 initialize 中有一个重要参数需要说明,那就是 nb_workers ,它将指定并行计算的Worker数,如果没有设置,所有CPU的核都会用上。
Pandarallel一共支持8种Pandas操作,下面是一个apply方法的例子。
import pandas as pd
import time
import math
import numpy as np
from pandarallel import pandarallel
# 初始化
pandarallel.initialize()
df_size = int(5e6)
df = pd.DataFrame(dict(a=np.random.randint(1, 8, df_size),
b=np.random.rand(df_size)))
def func(x):
return math.sin(x.a**2) + math.sin(x.b**2)
# 正常处理
res = df.apply(func, axis=1)
# 并行处理
res_parallel = df.parallel_apply(func, axis=1)
# 查看结果是否相同
res.equals(res_parallel)
其他方法使用上也是类似的,在原始的函数名称前加上 parallel_,比如 DataFrame.groupby.apply:
import pandas as pd
import time
import math
import numpy as np
from pandarallel import pandarallel
# 初始化
pandarallel.initialize()
df_size = int(3e7)
df = pd.DataFrame(dict(a=np.random.randint(1, 1000, df_size),
b=np.random.rand(df_size)))
def func(df):
dum = 0
for item in df.b:
dum += math.log10(math.sqrt(math.exp(item**2)))
return dum / len(df.b)
# 正常处理
res = df.groupby("a").apply(func)
# 并行处理
res_parallel = df.groupby("a").parallel_apply(func)
res.equals(res_parallel)
又比如 DataFrame.groupby.rolling.apply:
import pandas as pd
import time
import math
import numpy as np
from pandarallel import pandarallel
# 初始化
pandarallel.initialize()
df_size = int(1e6)
df = pd.DataFrame(dict(a=np.random.randint(1, 300, df_size),
b=np.random.rand(df_size)))
def func(x):
return x.iloc[0] + x.iloc[1] ** 2 + x.iloc[2] ** 3 + x.iloc[3] ** 4
# 正常处理
res = df.groupby('a').b.rolling(4).apply(func, raw=False)
# 并行处理
res_parallel = df.groupby('a').b.rolling(4).parallel_apply(func, raw=False)
res.equals(res_parallel)
案例都是类似的,这里就直接列出表格,不浪费大家宝贵的时间去阅读一些重复的例子了:
3.注意事项
1. 我有 8 个 CPU,但 parallel_apply 只能加快大约4倍的计算速度。为什么?
答:正如我前面所言,Python中每个进程占用一个核,Pandarallel 最多只能加快到你所拥有的核心的总数,一个 4 核的超线程 CPU 将向操作系统显示 8 个 CPU,但实际上只有 4 个核心,因此最多加快4倍。
2. 并行化是有成本的(实例化新进程,通过共享内存发送数据,…),所以只有当并行化的计算量足够大时,并行化才是有意义的。对于很少量的数据,使用 Pandarallel 并不总是值得的。
来源:https://blog.csdn.net/weixin_38037405/article/details/127064718


猜你喜欢
- 通过配置VIP,在进行主备切换时,出现的报错信息:1.当主备节点当前binlog文件名称相同时,原主节点的position小于主备切换后的p
- Web Forms 2.0 是一个很有意思的东东,是 HTML 5 的组成部分。它的目标是提升表单的使用性 (usability),基本上就
- 1.最小界面组成# 导入tkinter模块import tkinter# 创建主窗口对象root = tkinter.Tk()# 设置窗口大
- 我们大家都知道CSS功能的强大,而有关CSS基本的排版控制虽然已有详细的使用说明和参考教程,但还有许多丰富的CSS排版能力,是很少能查到的。
- 在Python中创建进程有两种方式,第一种是:from multiprocessing import Processimport timed
- 用于制作自动化微信聊天图片,通过图片生成段子视频根据一个txt文档input.txtL 一路走过来好热啊
- 一、绘制线性图形执行如下代码import matplotlib.pyplot as pltdataX=[1,2,3,4]dataY=[2,4
- 如何取得刚添加的记录自动增加的ID字段的号码?我们用下面这个程序就行:rs(1)=oldrname &nb
- python的验证码库(captcha)将验证码做成这样:是不是和各大网页的图片源地址是一样,话不多说,让我们看代码:我是用django和p
- 这篇文章主要介绍了Python socket模块方法实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
- 布尔类型是PHP中 最简单的类型。它的值可以为 TRUE 或 FALSE。如:$foo=false;$foo1=true;echo &quo
- 1、算术运算符:+、-、*、/、%。2、递增/递减运算符:如$a++,$a--,++$a,--$a.如:<?php$a=10;$b=5
- 本文实例讲述了Python接收Gmail新邮件并发送到gtalk的方法。分享给大家供大家参考。具体实现方法如下:#!/usr/bin/env
- 目录准备读取数据写入数据修改数据进阶用法最后准备首先,我们需要安装依赖包# 安装依赖包pip3 install 
- 下边是我对部分内容的总结,里边偏向了T-SQL语句实现的总结,对于SQL Server Management Studio中对象管理器的操作
- 在写一些很小的机器学习项目的时候,我们往往希望training, testing和inference能共用一个入口main,但是不同的功能使
- location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.hre
- PHP mysqli_sqlstate() 函数返回最后一个 MySQL 操作的 SQLSTATE 错误代码:<?php// 假定数据
- 在编写T-SQL代码时,往往需要临时存储某些结果集。前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量。除此之外,还可以使
- 一、根据条件在序列中筛选数据假设有一个数字列表 data, 过滤列表中的负数data = [1, 2, 3, 4, -5]# 使用列表推导式