导语

Polars 是一个使用 Apache Arrow 列格式作为内存模型,用Rust实现的,在Rust, Python以及Node.js中均可使用的速度极快的数据帧库。
它有以下几个特点:
  • 懒|立即执行
  • 多线程
  • SIMD
  • 查询优化
  • 强大的表达式API
  • 支持多种语言:Rust、Python 等
了解更多内容可以点击这个用户指南[1]

Python代码示例

>>> df = pl.DataFrame(

... {

... "A": [1, 2, 3, 4, 5],

... "fruits": ["banana", "banana", "apple", "apple", "banana"],

... "B": [5, 4, 3, 2, 1],

... "cars": ["beetle", "audi", "beetle", "beetle", "beetle"],

... }

... )


# embarrassingly parallel execution

# very expressive query language

>>> (

... df

... .sort("fruits")

... .select(

... [

... "fruits",

... "cars",

... pl.lit("fruits").alias("literal_string_fruits"),

... pl.col("B").filter(pl.col("cars") == "beetle").sum(),

... pl.col("A").filter(pl.col("B") > 2).sum().over("cars").alias("sum_A_by_cars"), # groups by "cars"

... pl.col("A").sum().over("fruits").alias("sum_A_by_fruits"), # groups by "fruits"

... pl.col("A").reverse().over("fruits").alias("rev_A_by_fruits"), # groups by "fruits

... pl.col("A").sort_by("B").over("fruits").alias("sort_A_by_B_by_fruits"), # groups by "fruits"

... ]

... )

... )

shape: (5, 8)

┌──────────┬──────────┬──────────────┬─────┬─────────────┬─────────────┬─────────────┬─────────────┐

│ fruits ┆ cars ┆ literal_stri ┆ B ┆ sum_A_by_ca ┆ sum_A_by_fr ┆ rev_A_by_fr ┆ sort_A_by_B │

│ --- ┆ --- ┆ ng_fruits ┆ --- ┆ rs ┆ uits ┆ uits ┆ _by_fruits │

│ str ┆ str ┆ --- ┆ i64 ┆ --- ┆ --- ┆ --- ┆ --- │

│ ┆ ┆ str ┆ ┆ i64 ┆ i64 ┆ i64 ┆ i64 │

╞══════════╪══════════╪══════════════╪═════╪═════════════╪═════════════╪═════════════╪═════════════╡

│ "apple" ┆ "beetle" ┆ "fruits" ┆ 11 ┆ 4 ┆ 7 ┆ 4 ┆ 4 │

├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤

│ "apple" ┆ "beetle" ┆ "fruits" ┆ 11 ┆ 4 ┆ 7 ┆ 3 ┆ 3 │

├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤

│ "banana" ┆ "beetle" ┆ "fruits" ┆ 11 ┆ 4 ┆ 8 ┆ 5 ┆ 5 │

├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤

│ "banana" ┆ "audi" ┆ "fruits" ┆ 11 ┆ 2 ┆ 8 ┆ 2 ┆ 2 │

├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤

│ "banana" ┆ "beetle" ┆ "fruits" ┆ 11 ┆ 4 ┆ 8 ┆ 1 ┆ 1 │

└──────────┴──────────┴──────────────┴─────┴─────────────┴─────────────┴─────────────┴─────────────┘

性能

Polars速度非常快,事实上,它是目前性能最好的解决方案之一。具体可参见h2oai's db基准测试结果[2]
此处我们自己用一些示例代码来对比python中pandas和polars处理数据的速度差距。
import pandas as pd

import polars as pl

import timeit


# 读取时间对比
start_df = timeit.default_timer()

df = pd.read_csv(
"/Users/lenskit/Desktop/aa.csv"
)

df = df.sort_values(
"company_name"
, ascending=False).head()

stop_df = timeit.default_timer()

print
(
'time: '
, stop_df - start_df)


start_pl = timeit.default_timer()

data = pl.read_csv(
"/Users/lenskit/Desktop/aa.csv"
)

data.sort(by=
"company_name"
, reverse=True).head()

stop_pl = timeit.default_timer()

print
(
'time1: '
, stop_pl - start_pl)


# 纵向拼接时间对比
start_df1 = timeit.default_timer()

df_1 = pd.read_csv(
'/Users/lenskit/Desktop/aa.csv'
)

df_2 = pd.read_csv(
'/Users/lenskit/Desktop/bb.csv'
)

df_1.append(df_2, ignore_index=True)

stop_df1 = timeit.default_timer()

print
(
'time2: '
, stop_df1 - start_df1)


start_pl1 = timeit.default_timer()

pl_1 = pl.read_csv(
'/Users/lenskit/Desktop/aa.csv'
)

pl_2 = pl.read_csv(
'/Users/lenskit/Desktop/bb.csv'
)

pl_1.vstack(pl_2)

stop_pl1 = timeit.default_timer()

print
(
'time3: '
, stop_pl1 - start_pl1)



time:  5.088931238

time1:  0.8967700230000002

time2:  4.707102063

time3:  0.639797883

可以看到在读取文件上,polars比pandas速度快了5倍多,在数据纵向拼接上,polars比pandas快了有7倍多。

Python安装

用如下语句安装最新的polars版本:
$ pip3 install -U polars[pyarrow]

目前polars的更新频率很高(每周/每隔几天),所以最好定期更新一下polars来获得最新的错误修复/功能。

Rust安装

您可以从crates.io获取最新版本,或者如果你想使用最新的功能/性能改进,可以用如下命令指向版本的master分支。
polars = { git = 
"https://github.com/pola-rs/polars"
, rev = 
"<optional git tag>"
 }


注意需要Rust version >=1.58

文档

想知道Polars支持的所有功能吗?阅读文档!
Python
  • 安装指南:$ pip3 install polars
  • Python文档[3]
  • 用户指南[4]
Rust
  • Rust文件(主分支)[5]
  • 用户指南[6]
Node
  • 安装指南:yarn install nodejs-polars
  • Node文档[7]
  • 用户指南[8]

[Python]: 从源代码编译polars

如果你想要获取最前沿的版本或最大的性能,你应该从源代码编译Polar。
这可以通过按顺序执行以下步骤来完成:
  • 1、安装最新的Rust编译器[9]
  • 2、安装maturin[10]: $ pip3 install maturin
  • 3、选择以下任一:
  • 最快的二进制文件,非常长的编译时间:
  • $ cd py-polars && maturin develop --rustc-extra-args="-C target-cpu=native" --release
  • 较快的二进制文件,短一些的编译时间:
  • $ cd py-polars && maturin develop --rustc-extra-args="-C codegen-units=16 -C lto=
需要注意的是,Python实现的Rust crate被称为py-polars,以区别于Rust crate包polars本身。然而,Python包和Python模块都被命名为polars,所以你可以pip install polarsimport polars

Arrow2

Polars已经转移到arrow2[11]。Arrow2是Apache Arrow Columnar Format[12]更快、更安全的实现。Arrow2还具有更细粒度的代码库,有助于减少编译器膨胀。

参考资料

[1]
用户指南: https://pola-rs.github.io/polars-book/
[2]
h2oai's db基准测试结果: https://h2oai.github.io/db-benchmark/
[3]
Python文档: https://pola-rs.github.io/polars/py-polars/html/reference/index.html
[4]
用户指南: https://pola-rs.github.io/polars-book/user-guide/index.html
[5]
Rust文件(主分支): https://pola-rs.github.io/polars/polars/index.html
[6]
用户指南: https://pola-rs.github.io/polars-book/user-guide/index.html
[7]
Node文档: https://pola-rs.github.io/polars/nodejs-polars/html/index.html
[8]
用户指南: https://pola-rs.github.io/polars-book/user-guide/index.html
[9]
Rust编译器: https://www.rust-lang.org/tools/install
[10]
maturin: https://maturin.rs/
[11]
arrow2: https://crates.io/crates/arrow2
[12]
Apache Arrow Columnar Format: https://arrow.apache.org/docs/format/Columnar.html

- EOF -
↓推荐关注↓

「开源前哨」日常分享热门、有趣和实用的开源项目。参与维护10万+star 的开源技术资源库,包括:Python, Java, C/C++, Go, JS, CSS, Node.js, PHP, .NET 等
点赞和在看就是最大的支持❤️
继续阅读
阅读原文