跳至主要内容

Polars 简介:面向大规模数据分析的 Python 工具

探索 Polars,这是一款用于高性能数据处理与分析的强大 Python 库。了解其功能、相较 pandas 的优势,以及它如何革新您的数据分析流程。
Moez Ali
Moez Ali

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续继续即表示您接受我们的 使用条款,我们的 隐私政策 ,并且您的数据存储在美国。

在数据分析领域,Python 以其多样性和庞大的库生态而广受欢迎。数据处理与分析对于提炼洞见、支持决策至关重要。然而,随着数据集在规模与复杂度上的不断增长,对高性能解决方案的需求愈发迫切。

要高效处理海量数据,需要能够提供快速计算与优化操作的工具。这正是 Polars 大显身手的地方。Polars 是一个专为 Python 中的高性能数据处理与分析而设计的强大开源库。

Polars 的特性

Polars 是一个完全由 Rust 编写的 DataFrame 库,旨在为 Python 开发者提供可扩展且高效的数据处理框架,被视为广受欢迎的 pandas 库的替代方案。它提供了广泛的功能,便于完成各类数据处理与分析任务。使用 Polars 的一些关键特性与优势包括:

1. 速度与性能

Polars 从设计之初就以性能为核心。它利用并行处理与内存优化技术,与传统方法相比,能够显著加速大数据集的处理。

2. 数据处理能力

Polars 提供了全面的数据处理工具集,涵盖过滤、排序、分组、连接与聚合等核心操作。尽管因为推出较晚,Polars 的功能广度尚不及 pandas,但它已覆盖 Pandas 中约 80% 的常见操作。

3. 表达性语法

Polars 采用简洁直观的语法,便于学习与使用。其语法风格与 pandas 等流行 Python 库相近,用户可以快速上手,并利用已有知识迁移到 Polars。

4. DataFrame 与 Series 结构

Polars 的核心是 DataFrame 与 Series 结构,为处理表格数据提供了熟悉而强大的抽象。在 Polars 中,DataFrame 操作可以链式组合,实现高效而简洁的数据转换。

5. 支持惰性求值

Polars 引入了惰性求值机制,会对查询进行分析与优化,以提升性能并降低内存消耗。使用 Polars 时,库会分析您的查询,寻找加速执行或减少内存占用的机会。相比之下,Pandas 仅支持即时求值,即在遇到表达式时立即计算。

已有 pandas,为什么还要选择 Polars?

pandas 作为被广泛采用的库,以其灵活和易用著称。然而,在处理大型数据集时,Pandas 因依赖单线程执行而可能出现性能瓶颈。随着数据集规模增大,处理时间会急剧拉长,从而影响效率。

Polars 专为高效处理大型数据集而设计。借助惰性求值策略与并行执行能力,Polars 能够快速处理海量数据。通过将计算分配至多个 CPU 内核,Polars 充分利用并行性,带来显著的性能提升。可参考 Yuki 对 Pandas 与 Polars 的速度对比测试。

image4.png

图片来源

关于 Polars 与 pandas 的完整对比,请查看我们的另一篇文章。

安装 Polars

可以通过 Python 包管理器 pip 安装 Polars。打开命令行并运行以下命令:

install polars

在 Polars 中加载数据集

Polars 提供了便捷的方法从多种来源加载数据,包括 CSV 文件、Parquet 文件和 Pandas DataFrame。读取 CSV 或 Parquet 文件的方法与 pandas 库相同。

# read csv file
import polars as pl
data = pl.read_csv('https://raw.githubusercontent.com/pycaret/pycaret/master/datasets/diamond.csv')


# check the head
data.head()

输出:

image2.png

data 的类型是 polars.DataFrame。

type(data)
>>> polars.dataframe.frame.DataFrame

输出:

image7.png

Polars 常用数据处理函数

Polars 提供了完整的数据处理功能集,便于您选择、过滤、排序、变换与清洗数据。下面通过示例了解一些常见的数据处理任务以及如何用 Polars 完成它们:

1. 选择与过滤数据

要从 DataFrame 中选择特定列,可使用 select() 方法。例如:

import polars as pl


# Load diamond data from a CSV file
df = pl.read_csv('https://raw.githubusercontent.com/pycaret/pycaret/master/datasets/diamond.csv')


# Select specific columns: carat, cut, and price
selected_df = df.select(['Carat Weight', 'Cut', 'Price'])


# show selected_df head
selected_df.head()

输出:

image1.png

基于条件过滤行可使用 filter() 方法。例如,要筛选克拉数大于 1.0 的行,可以这样做:

import polars as pl


# Load diamond data from a CSV file
df = pl.read_csv('https://raw.githubusercontent.com/pycaret/pycaret/master/datasets/diamond.csv')


# filter the df with condition
filtered_df = df.filter(pl.col('Carat Weight') > 2.0)


# show filtered_df head
filtered_df.head()

输出:

image9.png

2. 排序与排列数据

Polars 提供 sort() 方法,可按一个或多个列对 DataFrame 排序。例如:

import polars as pl


# Load diamond data from a CSV file
df = pl.read_csv('https://raw.githubusercontent.com/pycaret/pycaret/master/datasets/diamond.csv')


# sort the df by price
sorted_df = df.sort(by='Price')


# show sorted_df head
sorted_df.head()

输出:

image12.png

3. 处理缺失值

Polars 提供了便捷的缺失值处理方法。drop_nulls() 方法可删除包含任意缺失值的行:

import polars as pl


# Load diamond data from a CSV file
df = pl.read_csv('https://raw.githubusercontent.com/pycaret/pycaret/master/datasets/diamond.csv')


# drop missing values
cleaned_df = df.drop_nulls()


# show cleaned_df head
cleaned_df.head()

输出:

image5.png

或者,您可以使用 fill_nulls() 方法,用指定的默认值或填充方式替换缺失值。

4. 按特定列分组数据

要基于特定列对数据进行分组,可使用 groupby() 方法。以下示例按 Cut 列分组并计算每组的平均 Price:

import polars as pl


# Load diamond data from a CSV file
df = pl.read_csv('https://raw.githubusercontent.com/pycaret/pycaret/master/datasets/diamond.csv')


# group by cut and calc mean of price
grouped_df = df.groupby(by='Cut').agg(pl.col('Price').mean())


# show grouped_df head
grouped_df.head()

输出:

image8.png

从上述输出中,您可以看到按 Cut 维度划分的钻石平均价格。

5. 连接与合并 DataFrame

Polars 提供了灵活的 DataFrame 连接与合并选项,便于将来自不同来源的数据进行合并与拼接。要执行连接操作,可使用 join() 方法。以下示例演示了基于公共键列的两个 DataFrame 之间的内连接:

import polars as pl


# Create the first DataFrame
df1 = pl.DataFrame({
    'id': [1, 2, 3, 4],
    'name': ['Alice', 'Bob', 'Charlie', 'David']
})


# Create the second DataFrame
df2 = pl.DataFrame({
    'id': [2, 3, 5],
    'age': [25, 30, 35]
})


# Perform an inner join on the 'id' column
joined_df = df1.join(df2, on='id')


# Display the joined DataFrame
joined_df

输出:

image6.png

在该示例中,我们使用 pl.DataFrame 构造了两个 DataFrame(df1 与 df2)。第一个 DataFrame df1 包含 id 与 name 两列,第二个 DataFrame df2 包含 id 与 age 两列。随后我们在 id 列上使用 join() 方法执行内连接,并将 id 指定为连接键。

集成与互操作性

Polars 可与其他流行的 Python 库无缝集成,使数据分析师能够利用广泛的工具与功能。下面探讨集成的两个关键方面:与其他库协同工作,以及与 Pandas 的互操作性。

将 Polars 与其他 Python 库集成

Polars 可便捷地与 NumPy、PyArrow 等库集成,使用户在工作流中结合多种工具的优势。借助与 NumPy 的集成,Polars 可以在 DataFrame 与 NumPy 数组之间轻松转换,利用 NumPy 强大的科学计算能力。该集成确保数据顺畅过渡,并允许分析师将 NumPy 函数直接应用于 Polars 数据。

同样地,借助 PyArrow,Polars 优化了与基于 Arrow 的系统之间的数据传输。这一集成使得处理以 Arrow 格式存储的数据更加顺畅,并发挥 Polars 高性能数据处理能力。

将 Polars DataFrame 转换为 pandas DataFrame

Polars 提供了将 Polars DataFrame 无缝转换为 Pandas DataFrame 的能力。以下示例演示了从 Polars 到 pandas 的转换。

import polars as pl
import pandas as pd


# Create a Polars DataFrame
df_polars = pl.DataFrame({
    'column_A': [1, 2, 3],
    'column_B': ['apple', 'banana', 'orange']
})


# Convert Polars DataFrame to Pandas DataFrame
df_pandas = df_polars.to_pandas()


# Display the Pandas DataFrame
df_pandas

输出:

image3.png

总结

Polars 是一款用于 Python 中高性能数据处理与分析的强大库。其在速度与性能方面的优化,使其成为高效处理大型数据集的理想之选。

凭借表达性语法与 DataFrame 结构,Polars 为数据处理任务提供了熟悉而直观的界面。此外,Polars 能与 NumPy、PyArrow 等 Python 库无缝集成,扩展能力边界,使用户能够利用多样化的工具生态。

将 Polars DataFrame 转换为 pandas DataFrame 的能力,确保了互操作性,并便于将 Polars 集成到现有工作流中。无论您在处理复杂数据类型、应对大规模数据集,还是寻求性能提升,Polars 都提供了完整的工具集,助您释放数据分析工作的全部潜能。

Moez Ali

作者

Moez Ali

数据科学家,PyCaret 的创始人兼作者

主题