Pandas2.2中的新功能

Pandas2.2中的新功能

pandas2.2于2024年1月22日发布。让我们来看看这个版本带来了哪些变化,以及它将如何帮助我们改善pandas的工作负载。它包含一系列改进,将改善用户体验。

pandas2.2带来了一些依赖Apache Arrow生态系统的额外改进。此外,我们还为一些必要的更改添加了弃用项,以便在pandas3.0中将“写时复制”(Copy-on-Write)作为默认设置。让我们深入了解这对你意味着什么。我们将详细了解最重要的变化。如果你想了解更多关于pandas的相关内容,可以阅读以下这些文章:
pandas中的4种if-else技术,你应该使用哪一种?
每个Python Pandas开发人员都应该知道的提高生产力的十大库
每个Python数据分析师都应掌握的10个Pandas基本技巧
关于Pandas中最难的pivot_table,stack,unstack详解!

我是pandas核心团队的一员。作为Coiled的开源工程师,主要负责Dask,包括改进与pandas的集成。

我们在pandas2.0中引入了支持PyArrow的DataFrame,并从那时起不断改进集成,以实现与pandas API的无缝集成。pandas为某些dtypes提供了访问器来实现专门的操作,比如字符串访问器,它提供了许多字符串方法。从历史上看,list和structs是以NumPy对象dtype表示的,这使得处理它们相当麻烦。现在,Arrow dtype后端可以为列表和结构体提供量身定制的访问器,这使得处理这些对象变得更加容易。

让我们来看一个例子:

import pyarrow as pa

series = pd.Series(
[
{"project": "pandas", "version": "2.2.0"},
{"project": "numpy", "version": "1.25.2"},
{"project": "pyarrow", "version": "13.0.0"},
],
dtype=pd.ArrowDtype(
pa.struct([
("project", pa.string()),
("version", pa.string()),
])
),
)

这是一个每行都包含一个字典的系列。以前,只有在NumPy对象数据类型上才能实现这种操作,并且从这些行中访问元素需要对它们进行迭代。现在,结构访问器可以直接访问特定的属性。

series.struct.field("project")

0 pandas
1 numpy
2 pyarrow
Name: project, dtype: string[pyarrow]

下一个版本将带来基于箭头类型的CategoricalAccessor。

一直以来,pandas都依赖SqlAlchemy从Sql数据库中读取数据。这种方法工作非常可靠,但速度非常慢。Alchemy是按行读取数据的,而pandas采用的是列式布局,这使得读取数据并将其移入DataFrame的速度比必要的要慢。

Apache Arrow项目的ADBC驱动程序能让用户以列式布局读取数据,从而大大提高性能。它读取数据并将其存储到一个Arrow表中,然后将其转换为pandas DataFrame。如果为read_sql设置dtype_backend=”pyarrow”,就能实现零拷贝转换。

让我们来看一个例子:

import adbc_driver_postgresql.dbapi as pg_dbapi

df = pd.DataFrame(
[
[1, 2, 3],
[4, 5, 6],
],
columns=['a', 'b', 'c']
)
uri = "postgresql://postgres:postgres@localhost/postgres"
with pg_dbapi.connect(uri) as conn:
df.to_sql("pandas_table", conn, index=False)

# for round-tripping
with pg_dbapi.connect(uri) as conn:
df2 = pd.read_sql("pandas_table", conn)

ADBC驱动程序目前支持Postgres和Sqlite。我建议大家如果使用Postgres,就改用该驱动程序,因为该驱动程序的速度明显更快,而且完全避免了通过Python对象的往返,从而更可靠地保存数据库类型。这是我个人最感兴趣的功能。

从Sql到pandas,用户经常会错过case-when语法,该语法提供了一种简单明了的方法来有条件地创建新列。pandas 2.2添加了一个新的case_when方法,该方法定义在一个Series上。它的操作与Sql类似。

让我们来看一个示例:

df = pd.DataFrame(dict(a=[1, 2, 3], b=[4, 5, 6]))

default=pd.Series('default', index=df.index)
default.case_when(
caselist=[
(df.a == 1, 'first'),
(df.a.gt(1) & df.b.eq(5), 'second'),
],
)

该方法接收一系列按顺序评估的条件。然后,在条件求值为True的行中使用这些值创建新对象。该方法将大大方便我们创建条件列。

Copy-on-Write最初是在pandas 1.5.0中引入的。这种模式将在3.0中成为默认行为,这很可能是下一个pandas的发布版本。这意味着我们必须让我们的代码达到符合Copy-on-Write规则的状态。pandas 2.2引入了操作的弃用警告,因为这些操作将有所变化。

df = pd.DataFrame({"x": [1, 2, 3]})
df["x"][df["x"] > 1] = 100

这将引发FutureWarning。

FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!
You are setting values through chained assignment. Currently this works in certain cases, but when 
using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to 
update the original DataFrame or Series, because the intermediate object on which we are setting 
values will behave as a copy. A typical example is when you are setting values in a column of a 
DataFrame, like:

df["col"][row_indexer] = value

Use `df.loc[row_indexer, "col"] = values` instead, to perform the assignment in a single step and 
ensure this keeps updating the original `df`.

Copy-on-Write还有一个额外的警告模式,它会对所有改变行为的情况发出警告:

pd.options.mode.copy_on_write = "warn"

对于大多数pandas用户来说,这些警告大多只是噪音,这也是它们被隐藏在选项后面的原因。

pd.options.mode.copy_on_write = "warn"

df = pd.DataFrame({"a": [1, 2, 3]})
view = df["a"]
view.iloc[0] = 100

这将引发冗长的警告,解释将发生的变化:

FutureWarning: Setting a value on a view: behaviour will change in pandas 3.0.
You are mutating a Series or DataFrame object, and currently this mutation will
also have effect on other Series or DataFrame objects that share data with this
object. In pandas 3.0 (with Copy-on-Write), updating one Series or DataFrame object
will never modify another.

简而言之就是无论使用什么操作,更新view都不会更新df。这很可能大多数情况下都不相关。

我建议启用该模式并简要查看警告,但如果你确信不需要同时更新两个不同的对象,就不要过分关注它们。

我建议查看Copy-on-Write的迁移指南,该指南更详细地解释了必要的更改。

你可以通过以下方式安装新的pandas版本:

pip install -U pandas

或者

mamba install -c conda-forge pandas=2.2

这将为你提供新版本的环境。

我们已经研究了一些改进措施,将会提高pandas某些方面的性能和用户体验。最令人振奋的新功能将在pandas 3.0中推出,届时默认情况下将启用写时复制功能。

感谢阅读!你还可以订阅我们的YouTube频道,观看大量大数据行业相关公开课:https://www.youtube.com/channel/UCa8NLpvi70mHVsW4J_x9OeQ;在LinkedIn上关注我们,扩展你的人际网络!https://www.linkedin.com/company/dataapplab/

原文作者:Patrick Hoefler
翻译作者:Qing
美工编辑:过儿
校对审稿:Jason
原文链接:https://towardsdatascience.com/whats-new-in-pandas-2-2-e3afe6f341f5