基于DataFrame Country列值合并子区域列的性能优化问题
问题分析与优化方案
为什么你的代码运行极慢?
你的代码存在两个致命的效率问题,同时逻辑上也有错误:
- 循环内全量操作:你用
itertuples()遍历每一行,但每次循环里都对整个DataFrame执行apply操作。25万行的话,就相当于重复执行25万次全量列处理,这完全是不必要的冗余计算,直接把效率拉到谷底。 - 逻辑错误导致无效计算:
region = data['Country']这行取的是整个Country列的Series,不是当前行的Country值,所以你的if/elif判断根本不会按预期触发(因为一个Series和字符串比较的结果是布尔Series,永远不会是True)。实际效果是每次循环都在重复覆盖SubregionB列,做了大量无用功。 apply的额外开销:虽然apply比纯Python循环好,但它本质还是逐行处理,在可以用向量化操作的场景下,不是最优选择。
优化方案:用Pandas向量化操作批量处理
Pandas的核心优势是向量化运算,我们可以直接按Country的取值批量处理,避免任何行级循环,效率会提升几个数量级。这里有两种简洁高效的实现方式:
方法1:用loc按条件批量拼接
直接通过布尔索引定位不同Country的行,然后用字符串拼接(Pandas的字符串操作是向量化的,底层用C实现,速度极快):
import pandas as pd # 定位ARG和BRA的行,用"-"拼接 mask_arg_bra = data['Country'].isin(['ARG', 'BRA']) data.loc[mask_arg_bra, 'SubregionB'] = data.loc[mask_arg_bra, 'SubregionA'].astype(str) + ' - ' + data.loc[mask_arg_bra, 'SubregionB'].astype(str) # 定位USA的行,用空格拼接 mask_usa = data['Country'] == 'USA' data.loc[mask_usa, 'SubregionB'] = data.loc[mask_usa, 'SubregionA'].astype(str) + ' ' + data.loc[mask_usa, 'SubregionB'].astype(str)
方法2:用map匹配分隔符,统一拼接
先给每个Country映射对应的分隔符,再用向量化拼接一次性完成:
# 定义分隔符映射 sep_map = {'ARG': ' - ', 'BRA': ' - ', 'USA': ' '} # 生成每行对应的分隔符(其他国家默认用空分隔符,可按需调整) seps = data['Country'].map(sep_map).fillna('') # 批量拼接列内容 data['SubregionB'] = data['SubregionA'].astype(str) + seps + data['SubregionB'].astype(str)
效果对比
这两种方法都是全量向量化操作,不需要任何行循环,处理25万行数据的时间会从原来的分钟级(甚至更久)降到毫秒/秒级,完全解决性能问题。同时逻辑清晰,不会出现原代码的逻辑错误。
内容的提问来源于stack exchange,提问作者RoshanShah22
相关产品推荐
相关产品推荐

