pandas是基于python写的,底层的数据结构是Numpy数据(ndarray)。pandas自身有两个核心的数据结构:DataFrame和Series,前者是二维的表格数据结构,后者是一维标签化数组。
polars是用Rust(一种系统级编程语言,具有非常好的并发性和性能)写的,支持Python、Rust和NodeJS。主要特性有:
性能:pandas提供了强大的数据分析功能,对处理小数据集更方便。polars利用多线程和内存映射技术,具有更快的速度,适合处理大型数据集。
内存使用:Pandas在加载数据时需要将其完全读入内存;polars支持streaming API操作核外数据转化,可以在处理大型数据集时降低内存使用,从而减少了内存限制。
数据操作:pandas具有丰富的数据操作和处理方法,使用DataFrame进行数据清洗、转换、分组、聚合等操作;Polars提供了类似于SQL的查询操作,使得对数据进行筛选、转换和聚合更加直观。
生态系统:pandas已经非常成熟,具有大量的学习文档、教程和扩展库;polars相对较新,对应的文档、教程等资源较少。
适用场景:pandas更适用于中小型数据集的数据分析和处理;polars更适用于大型数据集或追求更高性能的数据分析和处理场景。
数据读取
# train.parquet: 2.35G
%time train_pd=pd.read_parquet('/Users/Downloads/archive/train.parquet') #Pandas dataframe
%time train_pl=pl.read_parquet('/Users/Downloads/archive/train.parquet') #Polars dataframe
CPU times: user 3.85 s, sys: 8.69 s, total: 12.5 s
Wall time: 10.4 s
CPU times: user 3.07 s, sys: 2.22 s, total: 5.29 s
Wall time: 3.39 s
聚合操作
%%time
# pandas query
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"]
train_pd[nums].agg(['min','max','mean','median','std'])
%%time
# 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'),
])
CPU times: user 6.06 s, sys: 4.19 s, total: 10.3 s
Wall time: 15.8 s
CPU times: user 4.51 s, sys: 5.49 s, total: 10 s
Wall time: 8.09 s
查询后计算
# Pandas filter and select
%time train_pd[train_pd['cat_1']==1][nums].mean()
# Polars filter and select
%time train_pl.filter(pl.col("cat_1") == 1).select(pl.col(nums).mean())
CPU times: user 730 ms, sys: 1.65 s, total: 2.38 s
Wall time: 4.24 s
CPU times: user 659 ms, sys: 3.22 s, total: 3.88 s
Wall time: 2.12 s
分类再聚合
%time Function_3= train_pd.groupby(['user'])[nums].agg('mean')
%time Function_3 = train_pl.groupby('user').agg(pl.col(nums).mean())
CPU times: user 2.4 s, sys: 938 ms, total: 3.33 s
Wall time: 3.46 s
CPU times: user 6.92 s, sys: 2.68 s, total: 9.6 s
Wall time: 1.78 s
分组的列逐渐增加
# PANDAS: TESTING GROUPING SPEED ON 5 COLUMNS
cols = []
for cat in ['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(f"{cat}:{round(en-st, 4)}s")
# POLARS: TESTING GROUPING SPEED ON 5 COLUMNS
cols = []
for cat in ['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(f"{cat}:{round(en-st, 4)}s")
每增加一列进行groupby后计算,所需要的时间:
cols 耗时 [“user”] 0.7666s [“user”,“cat_1”] 1.8221s [“user”,“cat_1”,“cat_2”] 9.4581s [“user”,“cat_1”,“cat_2”,“cat_3”] 15.1409s [“user”,“cat_1”,“cat_2”,“cat_3”,“cat_4”] 16.5913s
cols 耗时 [“user”] 0.498s [“user”,“cat_1”] 1.1978s [“user”,“cat_1”,“cat_2”] 3.4107s [“user”,“cat_1”,“cat_2”,“cat_3”] 4.4749s [“user”,“cat_1”,“cat_2”,“cat_3”,“cat_4”] 4.6821s
排序
cols=['user','num_8'] # columns to be used for sorting
# Sorting in Pandas
%time a = train_pd.sort_values(by=cols,ascending=True)
#Sorting in Polars
%time b = train_pl.sort(cols,descending=False)
CPU times: user 31.9 s, sys: 7.28 s, total: 39.2 s
Wall time: 46.2 s
CPU times: user 32.2 s, sys: 7.04 s, total: 39.2 s
Wall time: 11.6 s