如何提升pandas.apply()性能 实现大规模pandas列文本清洗
pandas文本清洗apply操作提速方案
你当前的操作慢,核心原因是Series.apply加lambda的写法本质是Python层逐行串行循环,没有用到pandas底层的C级优化,数据量上来之后性能会非常差。numpy.where不适合这个场景,它是用来做条件值选择的,不是用来加速逐元素文本转换的,硬用不会有任何提升。
下面按改造成本从低到高、性能提升从大到小给可行方案:
零成本小幅提速:去掉多余lambda,用map替换apply
Series.map针对逐元素转换的场景做了优化,运行开销比apply低,而且你完全不需要套一层lambda,直接传函数名即可,改完速度能提升15%-25%左右:
# 原写法:多了一层lambda的额外开销 # df['clean_text'] = df['text'].apply(lambda x: clean_text(x)) # 改后 df['clean_text'] = df['text'].map(clean_text)
数倍提升:优先用pandas原生向量化字符串操作
pandas的.str访问器下的方法都是底层C实现的向量化操作,比逐行跑Python函数快5-10倍,你现在clean_text里的lower()、strip()完全可以抽出来用原生方法跑,不需要放在逐行函数里:
# 先跑原生向量化的基础清洗 df['clean_text'] = df['text'].str.lower().str.strip()
如果你的remove_punct、remove_emoji是基于正则实现的,也完全可以改成.str.replace()的向量化调用,不需要逐行执行。举个去标点的例子:
# 逐行跑remove_punct的写法可以替换成向量化正则替换 import string df['clean_text'] = df['clean_text'].str.replace(f'[{string.punctuation}]', '', regex=True)
能改成向量化的逻辑尽量不要放在逐行函数里,这是性价比最高的提速手段。
十倍级提升:多核并行处理
如果数据量到了大几十万、百万级,前面的方法还是不够快,直接用多核并行把CPU所有核心用满,改造成本极低:
方案1:用swifter自动适配最优执行逻辑
swifter会自动判断你的函数能不能转成pandas原生向量化操作,能转就直接跑向量化,不能转就自动调用Dask做多核并行,不需要手动改函数逻辑:
- 先安装:
pip install swifter - 代码修改:
import swifter # 只需要把apply换成swifter.apply就行 df['clean_text'] = df['text'].swifter.apply(clean_text)
方案2:用Pandarallel做手动并行
如果想要更可控的并行逻辑,可以用Pandarallel,性能和swifter差不多:
- 先安装:
pip install pandarallel - 代码修改:
from pandarallel import pandarallel # 初始化时会自动检测你CPU的核心数 pandarallel.initialize(progress_bar=False) df['clean_text'] = df['text'].parallel_apply(clean_text)
8核CPU下这个写法比原生apply快6-7倍是很正常的。
容易忽略的性能坑
很多时候速度慢不是pandas的问题,是工具函数本身有冗余开销:
- 检查
remove_punct、remove_emoji里的正则是不是每次调用函数都重新编译?如果是,提前把正则表达式用re.compile()预编译成全局对象,只编译一次,速度能提升2-3倍。 - 检查停用词表是不是每次调用
remove_stopwords都重新从文件读取、重新转成set?如果是,把停用词表提前加载成全局的set对象,只加载一次,避免重复IO和类型转换。 - 不要在逐行函数里重复做已经用向量化方法完成的操作,比如已经用
.str.lower()转了小写,就不要在clean_text里再跑一次text.lower()。
不同方案100万行数据耗时参考
| 方案 | 预估耗时 | 改造成本 |
|---|---|---|
| 原apply+lambda写法 | 70-90s | 无 |
| map直接传函数 | 55-70s | 极低 |
| pandas原生str向量化 | 5-10s | 中 |
| swifter自动优化 | 8-15s | 极低 |
| pandarallel多核并行 | 10-15s | 低 |
内容的提问来源于stack exchange,提问作者Ravindra S
相关产品推荐
相关产品推荐

