高效使用Pandas:提升数据处理速度的七个技巧

203 admin
世界杯开球

Pandas 是 Python 的默认数据操作库。但如果你使用不当,只会给自己增加不必要的工作量。你见过有人逐行遍历 DataFrame 吗?简直是一种折磨,就像看到有人用牙刷洗车一样。

Pandas 很快,但前提是你知道如何使用它。问题是,大多数人并不了解。他们把它当作一个缓慢、笨重的电子表格,而不是一个优化的强大工具。他们本不应该使用循环的时候用了循环,误用函数,然后在数据集增长到数万行时,性能问题就出现了。

现实是:Pandas 构建在 NumPy 之上,而 NumPy 针对向量化操作进行了优化。也就是说,尽可能对整列进行操作,而不是逐行循环。然而,许多开发者本能地使用循环,因为这正是他们所习惯的。旧习惯难改。但在 Pandas 中,循环几乎总是最慢的方式。

不过,性能并不是唯一的问题。代码的可读性也很重要。如果你的 Pandas 代码看起来像是 .loc[]、.iloc[]、.apply() 和无尽条件语句的混乱组合,那么你不仅会让自己感到沮丧,也会让其他阅读你代码的人感到困惑。干净、高效的 Pandas 代码不仅仅是速度快,更是要让代码一目了然。

好消息是:Pandas 有一些内置的快捷方式,可以加速、简化操作,并减少挫败感。其中一些非常简单,比如使用向量化操作而不是循环。还有一些,比如 query() 或 merge(),只需要稍微改变一下思维方式,就能节省大量的精力。一些技巧甚至可以帮助减少内存使用,这在处理大型数据集时尤为重要。

这些不是“知道更好”的技巧,而是写出高效 Pandas 代码与写出普通代码的区别。如果你在处理金融数据、清理脏乱的 CSV 文件或处理数十万行数据,这七个技巧将为你的工作流程节省宝贵的时间。

前提条件

在开始之前,请确保你具备以下条件:

对 Python 和 Pandas 有基本了解一个可用的 Python 环境(Jupyter、VS Code,无论你偏好哪种)一些示例数据(CSV 文件、SQL 导出文件,任何可以练习的数据)已安装 Pandas(如果尚未安装,请运行 pip install pandas)

1. 停止使用循环——改用向量化操作

问题 循环很慢。如果你逐行遍历 DataFrame,那你就做错了。

为什么重要 Pandas 构建在 NumPy 之上,而 NumPy 针对快速的向量化操作进行了优化。这意味着你可以一次性对整个列进行计算,而不是使用循环。这种方式更快且更简洁。

解决方法 不要这样写:

import pandas as pd

df = pd.DataFrame({'a': range(1, 6), 'b': range(10, 15)})

df['c'] = [x * y for x, y in zip(df['a'], df['b'])]

要这样写:

df['c'] = df['a'] * df['b']

更快、更干净,且没有不必要的循环。

避免这个错误 .iterrows() 看起来是个好主意,但其实很慢。使用向量化操作或 .apply()(但仅在需要时使用,见技巧 #7)。

2. 使用 query() 更快地过滤数据

问题 使用布尔条件过滤数据很快就会变得复杂。

解决方法 不要这样写:

df[(df['a'] > 2) & (df['b'] < 14)]

要这样写:

df.query('a > 2 and b < 14')

更易读,且运行速度更快。

专业提示 如果需要在 .query() 中使用变量,请使用 @:

threshold = 2

df.query('a > @threshold')

3. 使用 astype() 节省内存

问题 大型 DataFrame 会消耗大量内存。

解决方法 尽可能降级数据类型:

df['a'] = df['a'].astype('int8')

使用以下命令检查内存使用情况:

df.info()

注意 降级浮点数可能会导致精度损失。除非需要 float64,否则请使用 float32。

4. 轻松处理缺失数据

问题 NaN 值会破坏计算。

解决方法

删除它们:df.dropna()填充它们:df.fillna(0)插值:df.interpolate()

专业提示 插值在处理时间序列数据时非常有用。

5. 使用 groupby() 更高效地处理数据

问题 手动汇总数据是浪费时间。

解决方法 使用 groupby() 快速聚合数据:

df.groupby('category')['sales'].sum()

需要多重聚合?使用 .agg():

df.groupby('category').agg({'sales': ['sum', 'mean']})

你知道吗? 你还可以使用 transform() 将聚合值添加回原始 DataFrame,而不会丢失原始行结构:

df['total_sales'] = df.groupby('category')['sales'].transform('sum')

6. 合并 DataFrame 而不拖慢代码

问题 不当的连接操作会拖慢一切。

解决方法 正确使用 merge():

df_merged = df1.merge(df2, on='id', how='inner')

最佳实践 如果要保留第一个 DataFrame 中的所有记录,请使用 how='left'。

性能提示 对于大型 DataFrame,确保连接键已索引以加快合并速度:

df1.set_index('id', inplace=True)

df2.set_index('id', inplace=True)

df_merged = df1.join(df2, how='inner')

7. 正确使用 .apply()(并避免过度使用)

问题 .apply() 功能强大,但经常被误用。

解决方法 将其用于复杂的逐行操作:

df['new_col'] = df['a'].apply(lambda x: x**2 if x > 2 else x)

但如果只是修改单列,请改用 .map(),它更快。

避免这个错误 不要在使用向量化操作可以完成任务时使用 .apply()。.apply() 比 Pandas 内置函数慢。

最后总结 这些技巧可以让你的 Pandas 工作流程更加顺畅、快速且易于阅读。不再有不必要的循环,不再有缓慢的连接,只有干净、高效的代码。

在你的下一个项目中试试这些技巧。如果你想进一步探索,请查看官方 Pandas 文档。

下一步建议:

在你的数据集上尝试这些技巧学习 Pandas 中的多级索引,以实现更强大的数据操作如果你处理的数据集太大,无法放入内存,可以探索 Dask

参考资料:

官方 Pandas 文档:pandas documentation — pandas 2.2.3 documentationJake VanderPlas 的《Python 数据科学手册》:Python Data Science Handbook | Python Data Science HandbookNumPy 文档:NumPy documentation — NumPy v2.2 Manual高效 Pandas:性能优化的最佳实践:Fast, Flexible, Easy and Intuitive: How to Speed Up Your pandas Projects – Real PythonWes McKinney 的 Pandas 性能提示:https://wesmckinney.com/blog/Dask 用于并行计算与 Pandas:Dask DataFrame — Dask documentation

32强小组赛行程谁最折腾? 世界杯地理大发现 Last Day on Earth: Survival 哈啦板