pandas和polars的常见用法对比

案例背景

最近上班需要处理的都是百万,千万级的数据,pandas的性能已经不够看了(虽然它在处理数据上是真的很好用),公司都是用的polar和pyspark,我最近也学习了一些,然后写篇文章对比一下他们的常见用法。虽然他们都有数据框dataframe这个数据结构,但是具体用法还是有很多差异的。


数据选取

都是做数据分析的,那么就用最简单的机器学习数据集波士顿房价数据集吧,演示以下常见的数据处理的用法。,然后画个图,简单机器学习一下。


代码实现

我这里就用data1表示pandas的数据结构,data2表示polar数据结构。2个数据结构的相同功能都用各种对应的语法展示。

导入包:

python 复制代码
import numpy as np
import pandas as pd
import polars as pl
import matplotlib.pyplot as plt 
import seaborn as sns

plt.rcParams ['font.sans-serif'] ='SimHei'               #显示中文
plt.rcParams ['axes.unicode_minus']=False               #显示负号

数据读取

首先是pandas的

python 复制代码
data1=pd.read_excel('Boston.xlsx')
data1.head(2)

这个其实polar差不多:

python 复制代码
data2=pl.read_excel('Boston.xlsx')  #要装一个什么csv2xlsx的包
data2.head(2)

写入文件

python 复制代码
#data1.to_csv(filepath)
#data2.write_csv(filepath)

这里就没运行了,但是是可用的,语法差不多。


查看数据基本信息

pandas很方便的info就行

python 复制代码
data1.info()

polar里面具有没有这个方法,见鬼,我只找到一个差不多的:

python 复制代码
data2.schema

这个只有数据类别,没得非空值什么的信息,差评。

其他的类型,变量名,数据形状,都是差不多:

python 复制代码
print(data1.dtypes) ;print(data2.dtypes)  #类型
print(data1.shape)  ;print(data2.shape)   #形状
print(data1.columns);print(data2.columns) #列名称

描述性统计

这是也是一样的,都是data.describe()就行

python 复制代码
data1.describe()
python 复制代码
data2.describe()

查看缺失值和填充

pandas 的我很熟悉

python 复制代码
print(data1.isnull().sum())
data1.fillna('2')

polars有些变化

python 复制代码
print(data2.null_count())
data2.fill_null('2')

数据切片

我觉得pandas 的数据切片真的很厉害,很逻辑完善。

python 复制代码
data1.loc[10:15,['CRIM','ZN']]

polars还没怎么用熟,不好评价

python 复制代码
data2.slice(10, 5).select(['CRIM', 'ZN'])   ##10是开始,5是行数

这里就得提一下了,polars没有索引这个东西,所以他的切片是用开始的位置和长度来穿入参数的。太离谱了,pandas的多层索引简直是诺贝尔奖发现好不好,polars居然没得索引这个东西,虽然简化一些东西,但是很多功能都丢失了。


数据筛选

语法差不多,各有优缺点吧

pandas

python 复制代码
data1[data1['MEDV'] >49.9 ]

polars

python 复制代码
data2.filter(data2['MEDV'] >49.9)

选两列数据

python 复制代码
data1[['NOX', 'RAD']]
python 复制代码
data2.select(['NOX', 'RAD'])

数据合并

pandas 的方法太多了:

python 复制代码
data1.merge(pd.Series(np.random.randint(0, 10, size=len(data1)),name='new'),left_index=True, right_index=True)
## 还可以pd.concat([]),还可以直接data1['new']=

polars这个名称是真离谱啊,合并了之后名称不知道怎么给,只能重命名

python 复制代码
##### 也是新增一列的用法
data2.with_columns(pl.Series('new1',np.random.randint(0, 10, size=len(data1)))).rename({'new1':'new'})

分组聚合

分组聚合麻烦起来很麻烦,可以写得超级复杂,咱们就简单求和试试

pandas:

python 复制代码
data1.groupby('RAD').sum()

polars差不多

python 复制代码
data2.groupby('RAD').sum()

删除缺失值

数据是没缺失值的,就随便演示一下了

python 复制代码
#data1.dropna()
data2.drop_nulls()

数据排序

pandas长一些

python 复制代码
data1.sort_values(['MEDV','B'],ascending=False)

polars短一点,且参数名称可能有点不一样

python 复制代码
data2.sort(by=['MEDV', 'B'],descending=True)

列名称重命名

panadas除了rename,其实还有很多方法的。

python 复制代码
data1.rename(columns={'MEDV':'y'})

polars也有rename,但是不能传入columns,而且他也有很多别的方法

python 复制代码
#data2.select(pl.col('MEDV').alias('10Medv'))  #挑选一行数据出来重命名
data2.select([ pl.col('NOX').alias('no'),
    pl.col('RAD').alias('yes')])   #挑选2行数据出来重命名
data2.rename({'MEDV':'y'})  #没索引这个概念,所以就不用传入形参

应用函数

简单的函数应该是差不多的,复杂的可以有区别,但是后面遇到再说

python 复制代码
data1['DIS'].apply(lambda x:str(x).split('.')[0])
python 复制代码
data2['DIS'].apply(lambda x:str(x).split('.')[0])

连接数据

pandas里面主要是merge函数

polars更像sql里面用join

python 复制代码
#data1.merge(data11, on='key')
#data2.join(data22, on='key')

删除某一列数据

两个一模一样

python 复制代码
data1.drop(columns=['MEDV'])
python 复制代码
data2.drop(columns=['MEDV'])

相互转化

polars数据结构也可以变成pandas和numpy的

python 复制代码
import pyarrow as pa
data2.to_pandas()  #需要安装pyarrow
#data2.to_numpy()  #也可以直接运行

链式法则

弄个复杂一点的代码段吧,来对比他们的区别

pandas的

python 复制代码
(data1.assign(sum_B=data1['B'].sum())  # 求和的
    .assign(sorted_MEDV=data1['MEDV'].sort_values())  # 排序的
    .assign(first_name=data1['RAD'].iloc[0])  # 第一个
    .assign(Medv=data1['MEDV'].mean() * 10)  # 10倍
)[['sum_B','sorted_MEDV','first_name','Medv']].sort_values('sorted_MEDV')

polars 的:

python 复制代码
data2.select(
    pl.sum('B'),  #求和的
    pl.col('MEDV').sort(),  #排序的
    pl.col('RAD').first().alias('first name'),  #第一个
    (pl.mean('MEDV')*10).alias('10Medv'),   #10倍
)

画图

pandas 的对象可以直接.plot画图的,也可以plt画图,我发现polars对象也能直接plt画图,还不错。

python 复制代码
plt.figure(figsize=(3,2))
data1['MEDV'].plot.box() # 只有padnas对象可以这样这个方法
#plt.boxplot(data1['MEDV']) #正常的plt画图
plt.boxplot(data2['MEDV'])   #pl数据也能用plt画图
plt.show()

机器学习

我们直接把polars数据结构扔到sklearn库里面去

python 复制代码
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
X = data2.drop(columns=['MEDV'])
y = data2['MEDV']
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

线性回归:

python 复制代码
# 线性回归
model =  LinearRegression()
model.fit(X_train, y_train)
model.score(X_test, y_test)

随机森林回归

python 复制代码
# 随机森林
model =  RandomForestRegressor()
model.fit(X_train, y_train)
model.score(X_test, y_test)

居然是和pandas一模一样的数据结果,还不错。


总结

感觉上来说,pandas和polars最大差异在于polars没得索引这个东西,并且很多 新增列,条件筛选,切片等等是存在一定的差异的,相似地方也有一些。最让我惊喜的是plt和sklearn可以完美兼容polars的数据结构,那就真的很不错了。


相关推荐
LZXCyrus15 分钟前
【杂记】vLLM如何指定GPU单卡/多卡离线推理
人工智能·经验分享·python·深度学习·语言模型·llm·vllm
Enougme18 分钟前
Appium常用的使用方法(一)
python·appium
懷淰メ23 分钟前
PyQt飞机大战游戏(附下载地址)
开发语言·python·qt·游戏·pyqt·游戏开发·pyqt5
我感觉。32 分钟前
【机器学习chp4】特征工程
人工智能·机器学习·主成分分析·特征工程
hummhumm37 分钟前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
DieYoung_Alive41 分钟前
一篇文章了解机器学习(下)
人工智能·机器学习
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
幻风_huanfeng1 小时前
人工智能之数学基础:线性代数在人工智能中的地位
人工智能·深度学习·神经网络·线性代数·机器学习·自然语言处理
请你喝好果汁6411 小时前
单细胞|M3-4. 细胞聚类与轨迹推断
机器学习·数据挖掘·聚类
每天吃饭的羊1 小时前
python里的数据结构
开发语言·python