Pandas 最简单的方法实现真正的并行

本文介绍一种简单的方法实现pandas的并行,从而实现数倍的速度提升,用到以下python库:

  • pandas
  • pandarallel

说明:pandarallel 只能在linux和mac os上使用,win党可以退了...

0. 闲扯

pandas 应该是应该python 中应用最广泛的数据处理库了,但是广为诟病的是速度处理比较慢,无法充分利用计算机的资源。在处理海量的数据或者文本时,我们希望能利用所有的CPU线程来加速。但是Python的多线程和多进程写起来比较麻烦,其中的多线程因为GIL(全局解释锁)的原因还是伪多线程。

在网上查找资料时,也有很多1行代码实现Python并行的文章,但是试验下来效果都不是很理想,比如在网上流传很广的 Parallelism in One Line,实际上用到 python 中的 map 函数,虽然是实现了多线程,但是每一个线程的利用率都很低,相比单线程基本上没有提升。

本文介绍一种能非常简单实现pandas并行的方法,用到了很小众的库:pandarallel,只需要1行代码就可以实现真正的并行。安装方法:

pip install pandarallel

以下通过一个具体的例子加以说明:求海量数组的平方。

1. 实验:

首先,我们来看pandas常规计算的代码耗时:

import time
import pandas as pd

def square(x):
    return x**2

nums_df=pd.DataFrame({"num":range(10000000)}) # 创建dataframe,包含1千万行

time_start=time.time()
nums_df["square"]=nums_df["num"].apply(square) # 计算数组所有数的平方
time_end=time.time()

print("常规代码耗时 %f s"%(time_end-time_start))  # 常规代码耗时 4.179099 s

这里,常规代码的耗时为 4.17s,首先说明,实验用的 CPU为 i3-9100f,是一个4核4线程的CPU。

然后我们再来看并行的代码耗时:

代码很简单,只要把数组导入到pandas的DataFrame中,然后应用apply即可。

但是这里应用的apply 是多线程版,叫做parallel_apply,在应用之前,需要做一个动作,就是导入pandarallel 并将它初始化。然后就没有然后了,废话不多说,上代码!

import time
import pandas as pd
from pandarallel import pandarallel # 导入pandaralle

pandarallel.initialize() # 初始化该这个b...并行库

def square(x):
    return x**2

nums=list(range(10000000))
nums_df=pd.DataFrame({"num":nums})

time_start=time.time()
nums_df["square"]=nums_df["num"].parallel_apply(square) # 计算数组所有数的平方,注意,用的是parallel_apply
time_end=time.time()

print("并行代码耗时 %f s"%(time_end-time_start))  # 并行代码耗时 1.465182 s

可以看到,并行代码耗时为1.46 s,通过简单的 parallel_apply,有接近3倍的速度提升。实际上,在线程数越多的CPU中,提升越明显。

2. 注意

虽然在上面的实例中看到,多线程版本的 parallel_apply 可以显著提升速度。但是它并不是在所有场景中都是有效的。

这个方法的本质上是把原来在一个线程上跑的计算,按元素分到多个线程跑,这就涉及到一个问题,分配和结果返回也是要消耗一定的时间的,如果计算本身消耗的时间比较少,那么多线程可能会更加耗时。

我个人将这个方法用在文本分词和预处理(去除停用词和符号等)上,比如 text_df["文本"].apply(jieba.cut_words) 改为 text_df["文本"].parallel_apply(jieba.cut_words)之后可以显著提升速度。但是也在一些场景下碰到速度反而下降的过程中,最明显的涉及到正则匹配的问题,多线程反而不如单线程快,不知道是什么原因,可能是python正则的底层是 C语言写的?

我个人的一个判断是,当某一个处理比较耗时,而且处理的元素可以分批,那么就可以通过这个方法实现显著的加速。举个例子来说:假如有100万的文本去重,我们写一个函数去两两比较文本的相似度,假如相似度大于80%,我们就只保留其中一条。

很显然,这是一个计算量非常大的任务,一种解决方法是通过simhash和数据结构来解决。另外一种简单粗暴的方法是,我们把这100万文本,分成100份,每一份有1万条文本,然后我们分别对1万条文本进行去重,然后去重之后再合并。这里,分别对1万条文本去重的过程,就可以用 text_df["text_batch"].parallel_apply(duplicate),个人实验下来,基本上有几个线程就可以提升几倍的速度。最后,当分批去重到一定程度的时候再合并去重,就可以大大减小计算量。

以上思考供大家参考,也欢迎各位在评论区指教。

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: Pandas是一个Python库,可以用它来实现分布式计算。首先,可以使用Pandas的read_csv函数读取要处理的数据集,然后使用Pandas的groupby函数对数据集进行分组,再使用Pandas的apply函数对每个分组进行计算,最后使用Pandas的to_csv函数将计算结果保存到文件中。 ### 回答2: PandasPython中一种常用的数据分析和处理库,通常在单机环境下使用。然而,我们也可以使用Pandas进行分布式计算,以便在集群或将数据分片处理时提高计算效率。下面是使用Pandas进行分布式计算的一种方法: 1.将数据分片:在进行分布式计算之前,我们需要将数据分片并将其分发到多个计算节点上。这可以通过原生的Python库或第三方库(如Dask)来实现。如果使用Dask库,可以使用`dask.dataframe` API将数据分片为多个小的Pandas DataFrame对象。 2.并行计算:在进行分布式计算之前,确保计算环境已正确设置并启动了多个计算节点,例如使用分布式系统(如Apache Spark或Hadoop MapReduce)。然后,我们可以使用分布式系统的并行计算功能来同时在多个计算节点上运行相同的Pandas操作。这意味着可以在每个分片上独立执行Pandas操作,从而节省了大量的计算时间。 3.结果合并:在并行计算完成后,将多个计算节点的结果合并为一个结果。这可以使用Pandas的合并操作,例如使用`concat`函数将多个分片的结果连接在一起。如果分布式系统提供了合并功能(如Apache Spark的reduce操作),则可以直接使用该功能将结果合并为一个整体。 4.性能优化:在进行分布式计算时,为了提高计算性能,我们可以考虑以下几点优化措施: a.使用更高效的数据结构:Pandas提供了多种数据结构,选择适用于具体计算任务的数据结构可以提高计算效率。 b.内存管理:对于大数据集,合理管理内存使用是重要的。我们可以使用Pandas的`chunksize`参数分块载入数据,避免一次性加载过多数据,从而减少内存压力。 c.合理选择分布式系统和集群资源:不同的分布式系统和集群资源具有不同的特性和优化策略,根据具体的分布式计算需求选择适合的系统和资源。 以上是一种使用Pandas进行分布式计算的简单介绍和方法。使用Pandas进行分布式计算可以提高计算效率和扩展性,在大规模数据处理和分析中具有广泛的应用。 ### 回答3: 在使用Pythonpandas库进行分布式计算时,可以使用以下方法: 1. 使用Dask库:Dask是Python的分布式计算库,它可以与pandas库完美集成。可以通过用dask.dataframe创建代理来实现pandas数据框转化为Dask数据框,从而实现分布式计算。Dask允许将数据集划分为多个块,并同时在多个节点上进行计算。这种方式可以提高计算效率和扩展性。 2. 使用PySpark:如果有一个较大的数据集需要进行分布式计算,可以使用Apache Spark的Python接口PySpark。PySpark提供了pandas DataFrame和Spark DataFrame之间的转换,可以使用pandas进行数据预处理和清洗,然后将数据转换为Spark DataFrame,利用Spark的分布式计算能力进行高效的数据分析和处理。 3. 使用并行计算:另一种方法是使用Python的多进程或多线程进行并行计算。可以使用multiprocessing或concurrent.futures等库来实现并行计算,将数据划分为多个部分,分配给不同的进程或线程进行计算。在多核或多机环境中,这种方法可以充分利用计算资源,提高计算效率。 无论采用哪种方法,都需要注意以下几点: 1. 数据划分:将较大的数据集划分为多个部分,并在处理之前进行数据划分。划分的方式可以根据具体需求选择:按行、按列划分,或者根据某个特征值进行分组划分。 2. 并行化操作:在进行分布式计算时,需要将计算任务分配给不同的处理节点,确保每个节点都有足够的计算资源。可以使用并行化的操作,例如将数据划分为多个块,使用map、reduce等操作来同时处理多个块。 3. 结果合并:在分布式计算完成后,需要将结果合并为一个整体。可以使用concat、merge等操作将分布式计算的结果合并为一个数据框。 总之,使用pandas进行分布式计算需要选择适当的工具和方法,并进行数据划分、并行化操作以及结果合并等处理来实现高效的分布式计算。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值