Pandas 2.0 vs Polars:速度的全面对比

简介: 前几天的文章,我们已经简单的介绍过Pandas 和Polars的速度对比。刚刚发布的Pandas 2.0速度得到了显著的提升。但是本次测试发现NumPy数组上的一些基本操作仍然更快。并且Polars 0.17.0,也在上周发布,并且也提到了性能的改善,所以我们这里做一个更详细的关于速度方面的评测。

本文将比较Pandas 2.0(使用Numpy和Pyarrow作为后端)和Polars 0.17.0的速度。并且介绍使用Polars库复现一些简单到复杂的Pandas代码,这样也算是对Polars的一个简单介绍。另外测试将在4 cpu和32 GB RAM上进行。

安装

可以通过pip命令进行安装

 pipinstallpolars==0.17.0# Latest version
 
 pipinstallpandas==2.0.0  # Latest pandas version

我们需要使用下面的库:

 importpandasaspd
 importpolarsaspl
 importnumpyasnp
 importtime

为了评估性能,我们将使用一个由3000万行和15列组成的合成数据集。该数据集由8个分类特征和7个数字特征组成,是人工生成的。数据集的链接在最后会提供。

下面显示了该数据集的一个示例

读取数据集

比较两个库读取parquet文件的时间。我使用了下面的代码,并使用%%time来获取代码执行的时间。

 train_pd=pd.read_parquet('./train.parquet') #Pandas dataframe
 
 train_pl=pl.read_parquet('./train.parquet') #Polars dataframe

可以看到Polars和Pandas 2.0在速度方面表现相似(因为都是arrow)但是Pandas(使用Numpy后端)需要两倍的时间来完成这个任务(这可能是因为有类型转换的原因,因为最终要把类型转成np的类型)。

聚合操作

下面的代码,该代码计算聚合(最小值、最大值、平均值)。

 # pandas query
 train_pd[nums].agg(['min','max','mean','median','std')
 train[cats].agg(['nunique'])
 
 # Polars query
 train_pl.with_columns([
     pl.col(nums).min().suffix('_min'),
     pl.col(nums).max().suffix('_max'),
     pl.col(nums).mean().suffix('_mean'),
     pl.col(nums).median().suffix('_median'),
     pl.col(nums).std().suffix('_std'),
     pl.col(cats).nunique().suffix('_unique'),
 ])

对于简单的聚合,Pandas在语法和性能方面会更好,但是差距并不大。

筛选操作

选择操作涉及根据条件进行查询和提取,例如下面代码

查询1:当nums_8小于10时,统计唯一值。

 # Polars filter and select
 train_pl.filter(pl.col("num_8") <=10).select(pl.col(cats).n_unique()) 
 
 # Pandas filter and select
 train_pd[train_pd['num_8']<=10][cats].nunique()

查询2:当cat_1 = 1时,计算所有数值列的平均值。

 # Polars filter and select
 train_pl.filter(pl.col("cat_1") ==1).select(pl.col(nums).mean())
 
 # Pandas filter and select
 train_pd[train_pd['cat_1']==1][nums].mean()

两个查询的结果如下:

在性能方面,Polars的数值filter速度要快2-5倍,而Pandas需要编写的代码更少。Pandas在处理字符串(分类特征)时速度较慢,这个我们在以前的文章中已经提到过,并且使用df.query函数在语法上更简洁,并且在大数据量的情况下会更快,这个如果有人有兴趣,我们再单独总结。

分组操作

分组操作是机器学习中用于创建聚合特征的基本操作之一,我在下面的通过user进行分组后,进行聚合来测试性能

函数1:统计cat_1的聚合特征

函数2:num_7的均值特征

函数3:所有数值列的平均聚合特征

函数4:计算分类列的聚合特性

 nums=['num_7','num_8', 'num_9', 'num_10', 'num_11', 'num_12', 'num_13', 'num_14','num_15']
 cats=['cat_1', 'cat_2', 'cat_3', 'cat_4', 'cat_5', 'cat_6']
 
 # Pandas Functions
 Function_1=train_pd.groupby(['user'])['cat_1'].agg('count')   #Function 1
 Function_2=train_pd.groupby(['user'])['num_7'].agg('mean')    #Function 2
 Function_3=train_pd.groupby(['user'])[nums].agg('mean')       #Function 3
 Function_4=train_pd.groupby(['user'])[cats].agg('count')      #Function 4
 
 
 # Polars Functions
 Function_1=train_pl.groupby('user').agg(pl.col('cat_1').count()) #Function 1
 Function_2=train_pl.groupby('user').agg(pl.col('num_7').mean())  #Function 2
 Function_3=train_pl.groupby('user').agg(pl.col(nums).mean())     #Function 3
 Function_4=train_pl.groupby('user').agg(pl.col(cats).count())    #Function 4

可以看到Polars非常快。但是Pyarrow后端的Pandas 2.0在所有情况下都明显比Polars和Pandas 2.0 (numpy后端)慢。

我们将分组变量的数量从1增加到5,看看结果:

 # PANDAS: TESTING GROUPING SPEED ON 5 COLUMNS
 forcatin ['user', 'cat_1', 'cat_2', 'cat_3', 'cat_4']:
   cols+=[cat]
   st=time.time()
   temp=train_pd.groupby(cols)['num_7'].agg('mean')
   en=time.time()
   print(cat,':',en-st)
 
 
 # POLARS: TESTING GROUPING SPEED ON 5 COLUMNS
 forcatin ['user', 'cat_1', 'cat_2', 'cat_3', 'cat_4']:
   cols+=[cat]
   st=time.time()
   temp=train_pl.groupby(cols).agg(pl.col('num_7').mean())
   en=time.time()
   print(cat,':',en-st)
   deltemp

下图中没有显示Pyarrow的Pandas 2.0,因为求值需要1000多秒。

对于group操作来说Polars是首选,但是Pandas在分组时默认删除空值,而Polars库则不会,这是一个小小的差异,在使用时需要注意。

排序操作

下面的代码,可以基于一个或多个列(升序或降序)快速对数据进行排序。

 cols=['user','num_8'] # columns to be used for sorting
 
 #Sorting in Polars
 train_pl.sort(cols,descending=False)
 
 # Sorting in Pandas
 train_pd.sort_values(by=cols,ascending=True)

从上图可以看出,对于排序和分组等复杂情况,Polars仍然是最快的库。Pandas对数据进行简单排序需要几分钟的时间,但在polar中,复杂的排序函数可以在不超过15秒的时间内计算出来。

总结

本文对Pandas和polar之间性能差异做了一个对比总结。Pandas在语法上更有吸引力(因为用的多习惯了),而Polars在处理更大的数据时提供了更好的吞吐量。

但是由于Polars是一个较新的库,从Pandas过渡到其他库具是有挑战性的。通过了解这两种强大工具之间的差异,我们可以根据自己的特定需求选择最佳选项,并实现更高效和有效的数据分析。

本文的数据下载:

https://avoid.overfit.cn/post/9d617b39040441e39433fc906cafefc9

作者:Priyanshu Chaudhary

目录
相关文章
|
机器学习/深度学习 存储 JSON
从Pandas快速切换到Polars :数据的ETL和查询
对于我们日常的数据清理、预处理和分析方面的大多数任务,Pandas已经绰绰有余。但是当数据量变得非常大时,它的性能开始下降。
233 0
|
Rust 分布式计算 安全
Pandas 2.0正式版发布: Pandas 1.5,Polars,Pandas 2.0 速度对比测试
Pandas 2.0正式版在4月3日已经发布了,以后我们pip install默认安装的就是2.0版了,Polars 是最近比较火的一个DataFrame 库,最近在kaggle上经常使用,所以这里我们将对比下 Pandas 1.5,Polars,Pandas 2.0 。看看在速度上 Pandas 2.0有没有优势。
229 0
Pandas 2.0正式版发布: Pandas 1.5,Polars,Pandas 2.0 速度对比测试
|
SQL 分布式计算 Scala
Pandas vs Spark:获取指定列的N种方式
本篇继续Pandas与Spark常用操作对比系列,针对常用到的获取指定列的多种实现做以对比。 注:此处的Pandas特指DataFrame数据结构,Spark特指spark.sql下的DataFrame数据结构。
547 0
Pandas vs Spark:获取指定列的N种方式
|
存储 分布式计算 文字识别
Pandas vs Spark:数据读取篇
按照前文所述,本篇开始Pandas和Spark常用数据处理方法对比系列。数据处理的第一个环节当然是数据读取,所以本文就围绕两个框架常用的数据读取方法做以介绍和对比。
301 0
Pandas vs Spark:数据读取篇
|
C语言 C++ Python
pandas VS baseR
import numpy as np import pandas as pd 创建DataFrame In [2]: df = pd.DataFrame({'col_a': np.
1050 0
|
9天前
|
数据挖掘 数据处理 索引
python常用pandas函数nlargest / nsmallest及其手动实现
python常用pandas函数nlargest / nsmallest及其手动实现
25 0
|
9天前
|
Python
如何使用Python的Pandas库进行数据透视图(melt/cast)操作?
Pandas的`melt()`和`pivot()`函数用于数据透视。基本步骤:导入pandas,创建DataFrame,然后使用这两个函数变换数据。示例代码:导入pandas,定义一个包含&#39;Name&#39;和&#39;Age&#39;列的DataFrame,使用`melt()`转为长格式,再用`pivot()`恢复为宽格式。
19 1
|
10天前
|
数据处理 Python
如何使用Python的Pandas库进行数据排序和排名
【4月更文挑战第22天】Pandas Python库提供数据排序和排名功能。使用`sort_values()`按列进行升序或降序排序,如`df.sort_values(by=&#39;A&#39;, ascending=False)`。`rank()`函数用于计算排名,如`df[&#39;A&#39;].rank(ascending=False)`。多列操作可传入列名列表,如`df.sort_values(by=[&#39;A&#39;, &#39;B&#39;], ascending=[True, False])`和分别对&#39;A&#39;、&#39;B&#39;列排名。
24 2
|
11天前
|
索引 Python
如何使用Python的Pandas库进行数据合并和拼接?
Pandas的`merge()`函数用于数据合并,如示例所示,根据&#39;key&#39;列对两个DataFrame执行内连接。`concat()`函数用于数据拼接,沿轴0(行)拼接两个DataFrame,并忽略原索引。
32 2
|
11天前
|
数据挖掘 索引 Python
如何在Python中,Pandas库实现对数据的时间序列分析?
【4月更文挑战第21天】Pandas在Python中提供了丰富的时间序列分析功能,如创建时间序列`pd.date_range()`,转换为DataFrame,设置时间索引`set_index()`,重采样`resample()`(示例:按月`&#39;M&#39;`和季度`&#39;Q&#39;`),移动窗口计算`rolling()`(如3个月移动平均)以及季节性调整`seasonal_decompose()`。这些工具适用于各种时间序列数据分析任务。
19 2