1 简介
本章将介绍 Python Polars 的基础知识。我们将学习 Polars 在高层次上的一些关键特性,以便理解 Polars 为何能快速、高效地处理数据。我们还将介绍如何利用 Polars 表达式对 DataFrame、Series 和 LazyFrame 进行基本操作。这些都是在数据工作流中开始使用 Polars 的基本知识和技巧。
主要内容:
Polars 的主要功能
Polars DataFrame
Polars 序列
Polars LazyFrame
选择列和过滤数据
创建、修改和删除列
了解方法链
处理大于 RAM 的数据集
完成所有这些操作后,您就能很好地理解 Polars 的独特之处,以及如何在 Polars 中应用基本数据操作。
1.1 技术要求
需要设置 Python 环境并安装和导入 Polars 库。以下是使用 pip 安装 Polars 库的方法:
$ pip install polars graphviz
安装:https://gitlab.com/graphviz/graphviz/-/releases
1.2 Polars的主要功能
Polars是一个速度极快的 DataFrame 库,允许您处理和转换结构化数据。它的设计目的是利用所有可用的 CPU 在一台机器上运行。
Python 中还有许多其他 DataFrame 库,包括 pandas 和 PySpark。Polars 是最新的 DataFrame 库之一。它性能卓越,正以迅雷不及掩耳之势受到越来越多人的欢迎。
DataFrame 是一个包含一个或多个 Series 的二维结构。系列是一维结构、数组或列表。你可以把 DataFrame 想象成一个表格,把 Series 想象成一列。然而,Polars 的功能远不止这些。一些概念和功能使 Polars 成为一个快速、高性能的 DataFrame 库。至少要对这些关键功能有一定程度的了解,才能最大限度地学习和有效使用 Polars。
从高层次来看,这些是 Polars 独特的关键功能:速度和效率、表达式、懒惰API。
1.2.1 速度和效率
我们知道Polars快速高效。但是,是什么促成了 Polars 今天的成就?有几个主要的组成部分促成了它的速度和效率:
Rust 编程语言
Apache Arrow 列式格式
懒API
Polars是用Rust编写的,这是一种低级编程语言,可提供与C/C++类似的性能和对内存的完全控制。由于Rust支持并发,Polars可以并行执行许多操作,无需任何配置即可利用计算机上的所有CPU。
此外,Polars 基于 Apache Arrow 的列式内存格式。这意味着 Polars 不仅可以利用列式内存的优化,还可以在其他基于 Arrow 的工具之间免费共享数据,而无需每次都复制数据(使用指向原始数据的指针,无需四处复制数据)。
最后,懒API(lazy API)通过实现其他几项查询优化,使 Polars 更快、更高效。我们稍后将在 “lazy API ”中介绍。
1.2.2 表达式
表达式使 Polars 的语法易读易用。它的表达式语法允许您以有组织、高效的方式编写复杂的逻辑。简单地说,表达式将序列作为输入,并将序列作为输出(将序列想象成表格或数据帧中的列)。您可以将多个表达式组合起来,建立复杂的查询。表达式链是使查询功能更强大的关键。
如下图所示,表达式接收序列并返回序列:
如下图所示,多个表达式相继作用于序列:
就表达式而言,上下文是一个重要概念。上下文本质上是对表达式进行评估的环境。换句话说,只要在上下文中暴露表达式,就可以使用表达式。在 Polars 中可以使用的上下文主要有以下三种:
选择
过滤
分组/聚合
在本书中,我们将介绍如何在这些上下文中使用表达式的具体示例和用例。当你学会理解表达式并在代码中广泛使用表达式时,你就会发现 Polars 的强大功能。
表达式是简洁的 Polars API 的一部分。这为您在 Polars 中构建数据转换逻辑提供了更好的人体工学设计和可用性。
1.2.3 懒API
通过应用额外的优化(如谓词下推和投影下推),lazy API 使 Polars 更快、更高效。它还会自动优化查询计划,这意味着 Polars 会找出执行查询的最佳方式。您可以使用 LazyFrame 访问懒 API,它是 DataFrame 的一个不同变体。
懒 API 使用懒评估,这是一种将表达式的评估延迟到需要结果值时再进行的策略。使用懒 API,Polars 可以端到端处理查询,而不是一次处理一个操作。您可以在 Polars 用户指南中查看懒 API 的完整优化列表:https://pola-rs.github.io/polars/user-guide/lazy/optimizations/。
懒 API 的另一项功能是流式处理或流式 API。它允许您处理大于机器可用内存量的数据。例如,如果你的笔记本电脑有 16 GB 内存,那么你就可以处理 50 GB 的数据。
不过,最好记住这是有限制的。虽然许多操作都可以使用这种大于内存的处理功能,但并非所有操作都可以使用(截至本书编写之时)。
急于求值(Eager evaluation)是另一种求值策略,即在调用表达式时立即对其进行求值。Polars DataFrame 和其他 DataFrame 库(如 pandas)默认使用该策略。
1.2.4 参考
要了解有关 Python Polars 工作原理的更多信息,包括其优化和机制,请参阅这些资源:
https://pola-rs.github.io/polars/
https://pola-rs.github.io/polars/user-guide/lazy/optimizations/
https://blog.jetbrains.com/dataspell/2023/08/polars-vs-pandas-what-s-the-difference/
Ritchie Vink Polars;快速完成,现在规模 PyCon 2023 – https://www.youtube.com/watch?v=apuFzB4j2_E&list=LL&index=5
Polars,你从未听说过的最快的 DataFrame 库 – https://www.youtube.com/watch?v=pzx99Mp52C8&list=LL&index=5
Polars,你从未听说过的最快的数据帧库。- Ritchie Vink | PyData Global 2021 – https://www.youtube.com/watch?v=iwGIuGk5nCE
https://pola-rs.github.io/polars-book-cn/user-guide/index.html
1.3 Polars DataFrame
DataFrame 是 Polars 的基础组件。在您开始 Polars 之旅时,值得学习其基础知识。DataFrame 就像一个有行和列的表格。它是 Polars 其他组件深度关联的基本结构。
如果你以前使用过 pandas 库,你可能会惊讶地发现 Polars 实际上并没有索引的概念。在 pandas 中,索引是一系列标识每一行的标签。它可以帮助你选择和对齐 DataFrame 中的行。这也与你在 SQL 数据库中看到的索引不同,pandas 中的索引并不是为了提高数据检索性能。
你可能会发现 pandas 中的索引很有用,但我打赌它们也会让你头疼。Polars 避免了索引带来的复杂性。如果你想了解更多关于 pandas 和 Polars 概念差异的信息,可以查看 Polars 文档中的这一页:https://pola-rs.github.io/polars/user-guide/migration/pandas。
我们将介绍创建 Polars DataFrame 的一些方法,以及提取 DataFrame 属性的实用方法。
从字典创建DataFrame
从文件创建DataFrame
.schemas在提供了每列名称和数据类型的字典。.columns 以列表的形式返回列名:
.dtypes 以列表的形式返回数据类型。df.dtypes返回数据帧大小,df.height返回行数、df.width返回列数。
df.flags返回表结构更详细的信息,类似数据字典
在pl.DataFrame() 添加了字典作为数据源。它的键是字符串,值是列表。除非你指定了模式,否则数据类型是自动输入的。在分析工作流中,.head() 方法非常方便。它会显示前 n 行,其中 n 是你指定的行数。n 的默认值为 5。pl.read_csv() 是将数据读入 DataFrame 的常用方法之一。它需要指定要读取文件的路径。它有许多参数,可以帮助你根据使用情况高效加载数据。
Polars DataFrame 可以将多种形式的数据作为源数据,如 Python 字典、Polars Series、NumPy 数组、pandas DataFrame 等。您甚至可以使用 pl.from_numpy() 和 pl.from_pandas() 等函数直接从其他结构导入数据,而不是使用 pl.DataFrame()。
读入 DataFrame 和输出到其他结构(如 pandas DataFrame 和 pyarrow.Table)都是可能的。我们将在第 10 章 “与其他 Python 库的互操作性 ”中介绍这一点。
1.3.1 数据类型
Polars 中的数据类型基本上可以分为五类:
数值(Numeric)
字符串/分类(String/categorical)
日期/时间(Date/time)
嵌套(Nested)
其他(布尔、二进制等 Boolean, Binary)
在本书中,我们将讨论如何使用特定类型的数据,但在学习 Polars 的初期,最好先了解有哪些数据类型。
你可以在 Polars 文档页面查看完整的数据类型列表:https://pola-rs.github.io/polars/py-polars/html/reference/datatypes.html。
1.3.2 参考
请参阅 Polars 文档的各个部分,了解更多信息:
https://pola-rs.github.io/polars/py-polars/html/reference/dataframe
https://pola-rs.github.io/polars/py-polars/html/reference/api/polars.read_csv.html
https://pola-rs.github.io/polars/py-polars/html/reference/dataframe/attributes.html
https://pola-rs.github.io/polars/py-polars/html/reference/functions.html
参考资料
软件测试精品书籍文档下载持续更新 https://github.com/china-testing/python-testing-examples 请点赞,谢谢!
本文涉及的python测试开发库 谢谢点赞! https://github.com/china-testing/python_cn_resouce
python精品书籍下载 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
Linux精品书籍下载 https://www.cnblogs.com/testing-/p/17438558.html
1.4 Polars 序列(Series )
序列是 DataFrame 库中的重要概念。一DataFrame 若干Series 组成。序列就像列表或数组:它是存储值列表的一维结构。在 Python 中,Series 与列表或数组不同,它被视为表格中的一列,包含特定数据类型的数据点或值的列表。与 Polars DataFrame 一样,Polars Series 也有许多内置方法,您可以利用它们进行数据转换。在本食谱中,我们将介绍 Polars Series 的创建以及如何检查其属性。
从头开始创建序列
使用 .to_series()和.get_column()方法从DataFrame创建序列:
默认情况下,.to_series() 返回第一列。您可以通过索引指定列,也可以使用.get_columns():指定列名
使用 .shape 获取长度和宽度、.name 获取列名、.dtype可以获得数据类型
创建序列并获取其属性的过程与创建 DataFrame 相似。DataFrame 和 Series 还有许多其他通用方法。了解如何使用 DataFrame 意味着了解如何使用 Series,反之亦然。
与 DataFrame 一样,Series 也可以在 NumPy 数组和 pandas Series 等其他结构之间转换。我们不会在本书中详细讨论这个问题,但我们会在本书后面的第 10 章 “与其他 Python 库的互操作性 ”中讨论 DataFrame 的这个问题。
1.4.1 参考
如果您想了解更多,请访问 Polars 文档页面:https://pola-rs.github.io/polars/py-polars/html/reference/series/index.html。
1.5 Polars LazyFrame
使 Polars 更快、更高效的独特功能之一是它的 lazy API。懒 API 使用懒评估,这是一种延迟评估表达式的技术,直到需要其值时才进行评估。这意味着只有在需要时才执行查询。这使得 Polars 可以应用查询优化,因为 Polars 只有在您要求它这样做时,才能通过查看整个计算图来同时查看和执行多个转换步骤。另一方面,如果使用急于求值(DataFrame 使用的另一种求值策略),则每次表达式都要处理数据。从本质上讲,懒评估为您提供了更高效的数据处理方法。
您可以使用我们称之为 LazyFrame 的 Polars lazy API。如前所述,LazyFrame 允许自动优化查询并进行大于内存的处理。
之所以推荐使用 LazyFrame,只是因为它有更多的功能和能力来更好地处理数据。在本教程中,您将学习如何创建 LazyFrame 以及如何使用与 LazyFrame 相关的实用方法和函数。
从头开始创建 LazyFrame:
使用 .collect() 方法指示 Polars 处理数据
使用 .scan_csv() 方法从 .csv 文件创建 LazyFrame:
使用 .lazy() 方法从 DataFrame 转换 LazyFrame:
显示 LazyFrame 的模式和宽度:
LazyFrame 的结构与 DataFrame 相同,但在使用 .collect() 命令之前,LazyFrame 不会处理查询。您可以使用它来触发 LazyFrame 的计算图或查询的执行。此操作可将 LazyFrame 具体化为 DataFrame。
请注意,DataFrame 中的某些操作在 LazyFrame 中不可用(如 .pivot())。这些操作需要 Polars 知道数据的整个结构,而 LazyFrame 无法处理这些操作。不过,一旦使用 .collect() 将 DataFrame 实体化,您就可以对其使用所有可用的 DataFrame 方法。
创建 LazyFrame 的方法与创建 DataFrame 的方法类似。创建 LazyFrame 后,一旦使用 .collect() 将其具体化,LazyFrame 就会转换为 DataFrame。这就是为什么在调用 .collect() 后可以调用 .head() 的原因。
在 Polars 0.20.31 版之前一直可用的 .fetch() 方法。虽然该方法在调试时非常有用,但也存在一些让用户困惑的问题。自 Polars 1.0.0 版起,该方法已被弃用。但仍可使用 ._fetch() 进行开发。
您会注意到,当您在 LazyFrame 中读取 .csv 文件或任何其他文件时,您使用的是扫描而不是读取。这样就能以懒惰模式读取文件,从而将列选择和筛选功能下放到扫描级别。基本上,你只需读取代码中执行操作所需的数据。你可以看到,这比先读取整个数据集,然后再进行筛选要有效得多。下一章将再次介绍文件的读写。
LazyFrame 的属性与 DataFrame 类似。不过,你需要通过 .collect_schema() 方法来访问这些属性。DataFrame 中也有相同的方法。
自 Polars 1.0.0 版起,在使用 .schema、.width、.dtypes 和 .columns 等 LazyFrame 属性时会收到性能警告。.collect_schema() 方法取代了这些方法。随着最近对懒惰引擎的改进和更改,解析模式不再是免费的,而且成本相对较高。为了解决这个问题,我们添加了.collect_schema() 方法。
好消息是,使用 .lazy() 和 .collect() 可以轻松地在 LazyFrame 和 DataFrame 之间来回切换。这样,您就可以在可能的情况下使用 LazyFrame,如果某些操作在 lazy API 中不可用,或者您不需要自动查询优化和大于内存处理等功能,则可以转换为 DataFrame。
LazyFrame 的一个独特功能是可以检查代码的查询计划。您可以使用 .show_graph() 或 .explain() 方法。.show_graph()方法将查询计划可视化,而.explain()方法只是使用.show_graph()将其打印出来:
π (pi) 表示列选择,σ (sigma) 表示过滤条件。
还没有介绍 .filter() 方法,但只要知道它用于过滤数据就可以了, 我们将在本章后面介绍它。
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/421187.html