Pandas 2.1有什么新功能
Pandas 2.1的新功能
关于新版本最有趣的事情

pandas 2.1于2023年8月30日发布。让我们来看看这个版本引入了哪些内容,以及它如何帮助我们改进pandas的工作负载。它包含了一系列的改进和一组新的废弃功能。
pandas 2.1在很大程度上建立在pandas 2.0中可用的PyArrow集成基础上。我们非常注重对新功能的支持,这些功能预计将成为pandas 3.0的默认功能。让我们深入了解这对您意味着什么。我们将详细介绍最重要的改进。
我是pandas核心团队的一员。我是Coiled的开源工程师,我在其中负责Dask,包括改进pandas的集成。
避免将字符串列转换为NumPy对象数据类型
pandas中一个主要的痛点是低效的字符串表示。我们在这个问题上花了相当长的时间进行研究。第一个基于PyArrow的字符串数据类型在pandas 1.3中可用。它有潜力将内存使用量减少约70%并提高性能。我在以前的文章中更深入地探讨了这个主题,包括内存比较和性能测量(总结:令人印象深刻)。
我们决定引入一个新的配置选项,将所有字符串列存储在PyArrow数组中。您不再需要担心转换字符串列,这将自动处理。
您可以使用以下代码打开此选项:
pd.options.future.infer_string = True
此行为将在pandas 3.0中成为默认行为,这意味着字符串列将始终由PyArrow支持。您需要安装PyArrow才能使用此选项。
PyArrow与NumPy对象数据类型具有不同的行为,这可能会使详细了解变得繁琐。我们实现了适用于此选项的字符串数据类型,以与NumPy的语义兼容。它的行为与NumPy对象列完全相同。我鼓励大家试一试!
改进的PyArrow支持
pandas 2.0中引入了基于PyArrow的DataFrame。我们过去几个月的一个主要目标是改进其在pandas中的集成。我们旨在使从基于NumPy的DataFrame切换尽可能简单。我们关注解决性能瓶颈,因为这之前导致了意外的减速。
让我们来看一个示例:
import pandas as pdimport numpy as npdf = pd.DataFrame( { "foo": np.random.randint(1, 10, (1_000_000, )), "bar": np.random.randint(1, 100, (1_000_000,)), }, dtype="int64[pyarrow]")grouped = df.groupby("foo")
我们的DataFrame有100万行和10个分组。让我们看看pandas 2.0.3与pandas 2.1在性能上的比较:
# pandas 2.0.310.6毫秒 ± 72.7微秒每次循环(平均值±7次运行的标准差,100次循环)# pandas 2.1.01.91毫秒±3.16微秒每次循环(平均值±7次运行的标准差,1,000次循环)
在新版本上,这个特定的示例快了5倍。merge
是另一个常用的函数,现在也会更快。我们希望使用基于PyArrow的DataFrame的体验现在更好了。
写时复制
写时复制最初在pandas 1.5.0中引入,并预计在pandas 3.0中成为默认行为。写时复制在pandas 2.0.x上已经提供了良好的体验。我们主要致力于修复已知的错误并提高其运行速度。我建议现在在生产环境中使用此模式。我编写了一系列的博客文章,解释了写时复制是什么以及它是如何工作的。这些博客文章详细介绍了写时复制的内部工作原理以及您可以从中期望的性能和行为。
我们已经看到,写时复制(Copy-on-Write)可以提高实际工作流程的性能超过50%。
废弃在setiten类操作中的静默向上转型
在历史上,如果您将不兼容的值设置到其中一个列中,pandas会自动更改该列的数据类型,但不会提示。让我们来看一个例子:
ser = pd.Series([1, 2, 3])0 11 22 3dtype: int64
我们有一个包含整数的Series,将导致其数据类型为整数。让我们将字母"a"
设置到第二行:
ser.iloc[1] = "a"0 11 a2 3dtype: object
这会将Series的数据类型更改为object。Object是唯一可以容纳整数和字符串的数据类型。这对许多用户来说是一个很大的痛点。对象列占用大量内存,计算将不再起作用,性能下降以及其他许多问题。它还在内部增加了许多特殊情况来适应这些问题。在过去,我的DataFrame中的静默数据类型更改是一个主要的烦恼。此行为现已被弃用,并将引发FutureWarning:
FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value 'a' has dtype incompatible with int64, please explicitly cast to a compatible dtype first. ser.iloc[1] = "a"
像我们示例中的操作将在pandas 3.0中引发错误。数据帧(DataFrame)的列的数据类型将在不同的操作中保持一致。当您想要更改数据类型时,您必须明确指定,这增加了一些代码,但对于未来的开发人员来说更容易理解。
此更改影响所有数据类型,例如,将浮点值设置到整数列中也会引发错误。
升级到新版本
您可以使用以下命令安装新版pandas:
pip install -U pandas
或者:
mamba install -c conda-forge pandas=2.1
这将在您的环境中安装新的发布版本。
结论
我们已经介绍了一些改进措施,这些措施将帮助您编写更高效的代码。包括性能改进,更容易选择PyArrow支持的字符串列和写时复制的进一步改进。我们还看到了一项废弃措施,这将使pandas的行为在下一个主要版本中更易于预测。
感谢您的阅读。欢迎随时联系以分享您的想法和反馈。