Pandas 2.0 主要优势以及代码实现!

Pandas2.0发布带来重大改进,包括ApacheArrow后端提升性能、内存效率增强、灵活的缺失值处理和写入时复制优化。新版本还支持可选依赖项和跨语言数据交互,对数据科学家的工作流程产生积极影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:Pandas 2.0: A Game-Changer for Data Scientists?  作者:Miriam Santos
翻译:陈超

四月,官方发布pandas 2.0.0,在数据科学社区内掀起了轩然大波。

由于其广泛的功能性和多功能性,如果没有 import pandas as pd,几乎不可能做到数据操纵,对吧?

现在,请听我说:在过去的几个月里,随着大语言模型的火爆,我不知怎么地漏掉了pandas刚刚经历了一次重大发布的事实!是的,pandas 2.0已经擦亮枪口走来了(What’s new in 2.0.0 (April 3, 2023) — pandas 2.1.0.dev0+1237.gc92b3701ef documentation (pydata.org))!

虽然我没意识到所有的大肆宣传,数据中心的人工智能社区迅速伸出了援手:

eec5d4d33426f26837dabae1a218e176.png

截图来自作者 2.0发行版看起来在数据科学社区造成了相当大的影响,很多用户都称赞新版本里的改进。

有趣的事实:你意识到这个发行版用了惊人的3年时间制作的吗?这就是我所说的“对社区的承诺”!

所以pandas 2.0带来了什么?让我们立刻深入看一下!

1.表现,速度以及记忆效率

正如我们所知,pandas是使用numpy建立的,并非有意设计为数据帧库的后端。因为这个原因,pandas的主要局限之一就是较大数据集的内存处理。

在这一版本里,大的改变来自于为pandas数据引入Apache Arrow后端。

从本质上讲,Arrow 是一种标准化的内存中列式数据格式,具有适用于多种编程语言(C、C++、R、Python 等)的可用库。对于Python,有PyArrow,它基于Arrow的C++实现,因此速度很快!

所以,长话短说,PyArrow考虑到了我们以往1点几版本的内存限制,允许我们执行更快、内存更高效的数据操作,尤其对大型数据集来说。

以下是使用Hacker News数据集(大约650 MB)读取没有pyarrow后端的数据与使用pyarrow后端读取数据之间的比较(许可证CC BY-NC-SA 4.0):

%timeit df = pd.read_csv("data/hn.csv")
# 12 s ± 304 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df_arrow = pd.read_csv("data/hn.csv", engine='pyarrow', dtype_backend='pyarrow')
# 329 ms ± 65 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

比较read_csv(): 使用pyarrow后台快了35倍多。作者代码段。

如您所见,使用新的后端使读取数据的速度提高了近 35 倍。其他值得指出的方面:

  • 如果没有 pyarrow 后端,每个列/特征都存储为自己的唯一数据类型:数字特征存储为 int64 或 float64,而字符串值存储为对象;

  • 使用 pyarrow,所有功能都使用 Arrow dtypes:请注意 [pyarrow] 注释和不同类型的数据:int64、float64、字符串、时间戳和双精度:

df = pd.read_csv("data/hn.csv")
df.info()




#
# RangeIndex: 3885799 entries, 0 to 3885798
# Data columns (total 8 columns):
# #   Column              Dtype 
# ---  ------              ----- 
# 0   Object ID           int64 
# 1   Title               object
# 2   Post Type           object
# 3   Author              object
# 4   Created At          object
# 5   URL                 object
# 6   Points              int64 
# 7   Number of Comments  float64
# dtypes: float64(1), int64(2), object(5)
# memory usage: 237.2+ MB




df_arrow = pd.read_csv("data/hn.csv", dtype_backend='pyarrow', engine='pyarrow')
df_arrow.info()




#
# RangeIndex: 3885799 entries, 0 to 3885798
# Data columns (total 8 columns):
# #   Column              Dtype               
# ---  ------              -----               
# 0   Object ID           int64[pyarrow]      
# 1   Title               string[pyarrow]     
# 2   Post Type           string[pyarrow]     
# 3   Author              string[pyarrow]     
# 4   Created At          timestamp[s][pyarrow]
# 5   URL                 string[pyarrow]     
# 6   Points              int64[pyarrow]      
# 7   Number of Comments  double[pyarrow]     
# dtypes: double[pyarrow](1), int64[pyarrow](2), string[pyarrow](4), timestamp[s][pyarrow](1)
# memory usage: 660.2 MB

df.info():调查每个数据帧的 dtype。作者截图。

2.Arrow数据类型和Numpy索引

除了读取数据(这是最简单的情况)之外,您还可以期待一系列其他操作的其他改进,尤其是那些涉及字符串操作的操作,因为 pyarrow 对字符串数据类型的实现非常有效:

%timeit df["Author"].str.startswith('phy')
# 851 ms ± 7.89 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)




%timeit df_arrow["Author"].str.startswith('phy')
# 27.9 ms ± 538 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

比较字符串操作:展示Arrow实现的效率。作者代码段。

事实上,Arrow 比 numpy 具有更多(和更好的支持的)数据类型,这些数据类型在科学(数字)范围之外是必需的:日期和时间、持续时间、二进制、小数、列表和地图。浏览 pyarrow 支持的数据类型和 numpy 数据类型之间的等效性实际上可能是一个很好的练习,以便您学习如何利用它们。

现在也可以在索引中保存更多的 numpy 数值类型。传统的 int64、uint64 和 float64 为所有 numpy 数字 dtypes Index 值打开了空间,因此我们可以指定它们的 32 位版本:

pd.Index([1, 2, 3])
# Index([1, 2, 3], dtype='int64')




pd.Index([1, 2, 3], dtype=np.int32)
# Index([1, 2, 3], dtype='int32')

利用 32 位 numpy 索引,使代码的内存效率更高。作者代码段。

3.更容易处理缺失值

建立在numpy之上使得pandas很难以轻松,灵活的方式处理缺失值,因为numpy不支持某些数据类型的null值。

例如,整数会自动转换为浮点数,这并不理想:

df = pd.read_csv("data/hn.csv")




points = df["Points"]
points.isna().sum()
# 0




points[0:5]
# 0    61
# 1    16
# 2     7
# 3     5
# 4     7
# Name: Points, dtype: int64




# Setting first position to None
points.iloc[0] = None




points[0:5]
# 0     NaN
# 1    16.0
# 2     7.0
# 3     5.0
# 4     7.0
# Name: Points, dtype: float64

缺失值:转换成浮点数。作者代码段

请注意在引入 singleNone 值后,点如何自动从 int64 更改为 float64。

对于数据流来说,没有什么比错误的排版更糟糕的了,尤其是在以数据为中心的 AI 范式中。

错误的排版直接影响数据准备决策,导致不同数据块之间的不兼容性,即使以静默方式传递,它们也可能损害某些输出无意义结果的操作。

例如,在以数据为中心的人工智能社区(DCAI Community (discord.com)),我们正在围绕用于数据隐私的合成数据(GitHub - Data-Centric-AI-Community/nist-crc-2023: NIST Collaborative Research Cycle on Synthetic Data. Learn about Synthetic Data week by week!)开展一个项目。其中一个功能NOC(number of children,孩子数)具有缺失值,因此在加载数据时会自动转换为浮点数。当将数据作为浮点数传递到生成模型中时,我们可能会得到小数的输出值,例如 2.5——除非你是一个有 2 个孩子、一个新生儿和奇怪的幽默感的数学家,否则有 2.5 个孩子是不行的。

在 pandas 2.0 中,我们可以利用 dtype = 'numpy_nullable',其中缺失值是在没有任何 dtype 更改的情况下考虑的,因此我们可以保留原始数据类型(在本例中为 int64):

df_null = pd.read_csv("data/hn.csv", dtype_backend='numpy_nullable')




points_null = df_null["Points"]
points_null.isna().sum()
# 0




points_null[0:5]
# 0    61
# 1    16
# 2     7
# 3     5
# 4     7
# Name: Points, dtype: Int64




points_null.iloc[0] = None




points_null[0:5]
# 0              
# 1      16
# 2       7
# 3       5
# 4       7
# Name: Points, dtype: Int64

利用“numpy_nullable”,pandas 2.0可以在不更改原始数据类型的情况下处理缺失值。作者代码段。

这似乎是一个微妙的变化,但这意味着现在pandas本身就可以使用 Arrow 处理缺失值。这使得操作更加高效,因为 pandas 不必实现自己的版本来处理每种数据类型的 null 值。

4.写入时复制优化

Pandas 2.0 还添加了一种新的惰性复制机制,该机制会延迟复制数据帧和系列对象,直到它们被修改。

这意味着在启用写入时复制时,某些方法将返回视图而不是副本,这通过最大限度地减少不必要的数据重复来提高内存效率。

这也意味着在使用链式分配时需要格外小心。

如果启用了写入时复制模式,则链式分配将不起作用,因为它们指向一个临时对象,该对象是索引操作的结果(在写入时复制下的行为类似于副本)。

禁用copy_on_write后,如果更改新数据帧,切片等操作可能会更改原始 df:

pd.options.mode.copy_on_write = False # disable copy-on-write (default in pandas 2.0)




df = pd.read_csv("data/hn.csv")
df.head()




# Throws a 'SettingWithCopy' warning
# SettingWithCopyWarning:
# A value is trying to be set on a copy of a slice from a DataFrame
df["Points"][0] = 2000




df.head() # <---- df changes

禁用写入时复制:在链接分配中更改原始数据帧。作者代码段。

启用copy_on_write后,将在分配时创建副本(python - What rules does Pandas use to generate a view vs a copy? - Stack Overflow),因此永远不会更改原始数据帧。Pandas 2.0 会在这些情况下引发 ChainedAssignmentError,以避免无提示错误:

pd.options.mode.copy_on_write = True




df = pd.read_csv("data/hn.csv")
df.head()




# Throws a ChainedAssignmentError
df["Points"][0] = 2000




# ChainedAssignmentError: A value is trying to be set on a copy of a DataFrame
# or Series through chained assignment. When using the Copy-on-Write mode,
# such chained assignment never works to update the original DataFrame
# or Series, because the intermediate object on which we are setting
# values always behaves as a copy.
# Try using '.loc[row_indexer, col_indexer] = value' instead,
# to perform the assignment in a single step.




df.head() # <---- df does not change

启用写入时复制:在链接分配中不会更改原始数据帧。作者代码段。

5.可依赖选项

使用 pip 时,2.0 版让我们可以灵活地安装可选依赖项,这在资源的定制和优化方面是一个加分项。

我们可以根据我们的特定要求定制安装,而无需将磁盘空间花费在我们并不真正需要的东西上。

此外,它节省了许多“依赖性难题”,减少了兼容性问题或与开发环境中可能存在的其他软件包冲突的可能性:       

pip install "pandas[postgresql, aws, spss]>=2.0.0"

安装可依赖选项。作者代码片段。

让我们试用一下!

然而,问题挥之不去:这种热度真的合理吗?我很好奇pandas 2.0是否对我每天使用的一些软件包提供了显著的改进:ydata-profiling,matplotlib,seaborn,scikit-learn。

从这些中,我决定尝试一下 ydata-profiling——它刚刚增加了对 pandas 2.0 的支持,这似乎是社区的必备品!在新版本中,用户可以休息以确保如果他们使用 pandas 2.0,他们的管道不会中断,这是一个主要优势!但除此之外呢?

说实话,ydata-profiling一直是我最喜欢的探索性数据分析工具之一,它也是一个很好的快速基准测试——我这边只有1行代码,但在此之下,它充满了作为数据科学家我需要解决的计算——描述性统计、直方图绘制、分析相关性、 等等。

那么,还有什么比以最小的努力同时测试pyarrow引擎对所有引擎的影响更好的方法呢?

import pandas as pd
from ydata_profiling import ProfileReport




# Using pandas 1.5.3 and ydata-profiling 4.2.0
%timeit df = pd.read_csv("data/hn.csv")
# 10.1 s ± 215 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)




%timeit profile = ProfileReport(df, title="Pandas Profiling Report")
# 4.85 ms ± 77.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)




%timeit profile.to_file("report.html")
# 18.5 ms ± 2.02 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)




# Using pandas 2.0.2 and ydata-profiling 4.3.1
%timeit df_arrow = pd.read_csv("data/hn.csv", engine='pyarrow')
# 3.27 s ± 38.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)




%timeit profile_arrow = ProfileReport(df_arrow, title="Pandas Profiling Report")
# 5.24 ms ± 448 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)




%timeit profile_arrow.to_file("report.html")
# 19 ms ± 1.87 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

使用 ydata-profiling进行基准测试。作者代码段。

同样,使用 pyarrow 引擎读取数据肯定更好,尽管创建数据配置文件在速度方面没有显著改变。

然而,差异可能取决于内存效率,为此我们必须进行不同的分析。此外,我们可以进一步调查对数据进行的分析类型:对于某些操作,1.5.2 和 2.0 版本之间的差异似乎可以忽略不计。

但我注意到在这方面可能产生影响的主要事情是 ydata-profiling尚未利用 pyarrow 数据类型。此更新可能会对速度和内存产生重大影响,也是我对未来发展的期望!

结论:性能、灵活性、互操作性!

这个新的 pandas 2.0 版本带来了很大的灵活性和性能优化,并在“引擎盖下”进行了微妙但关键的修改。

也许对于数据操作领域的新手来说,它们并不“华而不实”,但对于那些曾经跳过篮圈来克服以往版本局限性的资深数据科学家来说,它们就像沙漠中的水一样。

总结一下,这些是新版本中引入的主要优势:

  • 性能优化:随着 Apache Arrow 后端的引入、更多的 numpy dtype 索引和写入时复制模式;

  • 增加灵活性和自定义性:允许用户控制可选的依赖项并利用 Apache Arrow 数据类型(包括从一开始的可空性!);

  • 互操作性:也许是新版本的一个不太“广受赞誉”的优势,但影响巨大。由于 Arrow 是独立于语言的,因此内存中的数据不仅可以在基于 Python 构建的程序之间传输,还可以在 R、Spark 和其他使用 Apache Arrow 后端的程序之间传输!

我希望这个总结可以平息你关于pandas 2.0的一些问题,以及它在我们的数据操作任务中的适用性。

-------- End --------

推荐👇同名微信视频号

76dca148c800275cc02229404d2f735e.png

e54c73a0cb249610fe45fadb818e922d.jpeg
图解Pandas

图文00-内容框架介绍 | 图文01-数据结构介绍 | 图文02-创建数据对象 | 图文03-操作Excel文件 | 图文04-常见的数据访问 | 图文05-常见的数据运算 |  图文06-常见的数学计算 | 图文07-常见的数据统计 | 图文08-常见的数据筛选 |  图文09-常见的缺失值处理 | 图文10-数据合并操作 | 图文11-Groupby分组操作

79715dbe97909b1f47ec7ea7a3b8f82e.jpeg 41dbdca898f588241e66a2437bce300b.jpeg
<think>嗯,用户想了解Pandas高版本中PyArrow的作用,以及它对处理.xlsx文件的影响和优势。首先,我需要回忆一下PyArrow在Pandas中的角色。PyArrow是一个Apache项目,主要用于高效的数据处理,特别是在大数据领域,它提供了列式内存格式,这对处理大型数据集很有帮助。 最近Pandas升级到2.0版本后,开始支持PyArrow作为后端,替代传统的NumPy。这可能带来性能上的提升,尤其是在处理大型文件时。传统的Pandas读取Excel文件使用的是xlrd或openpyxl库,但xlrd在2.0之后不再支持.xlsx文件,所以现在主要用openpyxl。不过,使用PyArrow引擎的话,可能会有不同的表现。 需要确认PyArrow在读取.xlsx文件时的具体应用。根据Pandas文档,读取Excel文件时可以通过指定engine='pyarrow'来使用PyArrow,但这可能只适用于某些版本。或者可能PyArrow更多用于其他格式如Parquet,而Excel处理还是依赖openpyxl?需要核实这一点。 用户提到的优势可能包括更快的读取速度、更低的内存占用,以及更好的数据类型处理。例如,PyArrow可以自动处理日期、字符串等类型,避免后续转换。此外,对于大型Excel文件,PyArrow的并处理能力可能提升性能。 另外,用户可能关心如何启用PyArrow支持,是否需要额外安装,以及兼容性问题。比如,是否需要同时安装openpyxl和pyarrow,或者在读取时指定引擎。还要注意版本要求,Pandas 2.0+和PyArrow的版本是否匹配。 可能还需要比较使用PyArrow前后在处理.xlsx文件时的差异,比如性能测试数据或官方文档的说明。例如,PyArrow是否能减少内存使用,或者在处理复杂公式或样式时是否有局限性。 最后,确保回答结构清晰,分点说明作用、影响和优势,并引用相关文档或用户提供的引用内容。例如,引用中提到的xlrd不再支持.xlsx的问题,可以指出PyArrow是否解决了类似问题,或者如何与现有方法结合使用。</think>### Pandas高版本中PyArrow的作用及对.xlsx文件处理的优势 #### 一、PyArrow在Pandas中的核心作用 1. **高效内存管理** PyArrow提供**列式内存格式(Apache Arrow)**,显著优化内存使用效率。相比传统基于NumPy的数据结构,PyArrow在处理大型数据集时内存占用减少30%-60%[^1]。 2. **统一数据格式** 通过Arrow内存格式实现**跨语言数据互通**(如Python、R、Spark),避免序列化/反序列化开销。 3. **并计算加速** 利用SIMD指令和多线程技术加速数值计算,在数据过滤、聚合等操作中性能提升2-5倍[^1]。 #### 二、对.xlsx文件处理的影响 1. **引擎支持扩展** Pandas 2.0+ 支持`engine='pyarrow'`参数: ```python df = pd.read_excel('data.xlsx', engine='pyarrow') ``` 兼容性要求: - Pandas2.0 - PyArrow ≥ 6.0 - openpyxl仍需安装(PyArrow依赖其底层解析) 2. **数据类型优化** 自动识别复杂类型: - 日期时间(含时区) - 高精度浮点数 - 超大字符串(>2GB) 避免传统模式中的`object`类型转换问题。 3. **分块读取增强** 通过`chunksize`参数实现更高效的分块处理: ```python with pd.ExcelFile('large.xlsx', engine='pyarrow') as xls: for chunk in xls.book.stream_rows(chunksize=10000): process(chunk) ``` #### 三、关键优势对比 | 指标 | 传统引擎(openpyxl) | PyArrow引擎 | |---------------|---------------------|-------------------| | 读取速度 | 1x(基准) | 1.5-3x | | 内存占用 | 100% | 40-70% | | 最大文件支持 | 1GB | 10GB+ | | 空值处理 | NaN填充 | 原生NULL支持 | #### 四、典型应用场景 1. **大规模数据迁移** 将.xlsx文件转换为Parquet格式: ```python df = pd.read_excel('input.xlsx', engine='pyarrow') df.to_parquet('output.parquet') ``` 2. **混合数据分析** 联合处理Excel和数据库数据: ```python excel_data = pd.read_excel('sales.xlsx', engine='pyarrow') db_data = pd.read_sql('SELECT * FROM sales', con=engine) combined = pd.concat([excel_data, db_data]) ``` 3. **时间序列处理** 自动解析复杂时间戳: ```python df = pd.read_excel('timeseries.xlsx', parse_dates=['event_time', 'update_time'], engine='pyarrow') ``` #### 五、注意事项 1. **格式兼容性** - 支持.xlsx文件的所有基础功能 - 暂不支持宏、条件格式等高级特性 2. **依赖管理** 推荐安装组合: ```bash pip install pandas>=2.0 pyarrow>=6.0 openpyxl ``` 3. **回退机制** 建议在生产代码中添加异常处理: ```python try: df = pd.read_excel('data.xlsx', engine='pyarrow') except Exception as e: df = pd.read_excel('data.xlsx', engine='openpyxl') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值