Pandas dataframe逐行遍历速度过慢,如何无需逐行遍历实现新增列需求
Pandas逐行操作优化方案
你原来的代码性能差主要有两个核心问题:一是用iterrows逐行迭代,二是循环内每次调用df.replace触发全表扫描,完全可以用Pandas向量化操作实现同等逻辑,性能提升可达百倍以上。
优化后完整代码
import pandas as pd # 1. 预处理日期列,转成datetime格式 df['Event_Start_Time'] = pd.to_datetime(df['Event_Start_Time']) # 2. 生成Work_Week_Year(年份)和Work_Week列 df['Work_Week_Year'] = df['Event_Start_Time'].dt.year.astype(str) # 直接用一年中的第几天计算周数,替代原来手动累加月份天数的逻辑,结果完全一致 df['Work_Week'] = df['Event_Start_Time'].dt.dayofyear // 7 # 3. 处理TPRev列,去掉所有小数点 df['TPRev'] = df['TPRev'].astype(str).str.replace('.', '', regex=False) # 4. 映射生成ctqparam列 df['ctqparam'] = df['Subtest'].astype(str).map(ctqparam_dict) # 5. 按照你要求的位置插入列 df.insert(0, 'Work_Week_Year', df.pop('Work_Week_Year')) df.insert(3, 'Work_Week', df.pop('Work_Week')) df.insert(4, 'ctqparam', df.pop('ctqparam'))
特殊场景适配
如果你原来的months数组是自定义的非公历规则的周历计算逻辑,可以把月份累计天数提前做成字典,用以下方式计算Work_Week:
# 假设month_cum_days是1-12月对应的累计天数字典,比如{1:0, 2:31, 3:59...} df['month'] = df['Event_Start_Time'].dt.month df['day'] = df['Event_Start_Time'].dt.day df['total_days'] = df['month'].map(month_cum_days) + df['day'] df['Work_Week'] = df['total_days'] //7
逻辑说明
- 日期计算部分:直接调用Pandas内置的datetime属性
dt.year和dt.dayofyear,替代你手动切字符串、累加月份天数的逻辑,不仅代码更简洁,还自动兼容平闰年的天数差异 - TPRev字段处理:用向量化的字符串替换方法
str.replace,一次性处理全列,不需要逐行遍历 - ctqparam映射:用
map方法直接把字典映射到全列,性能远高于逐行判断 - 全程没有任何逐行循环操作,所有计算都是Pandas底层用C实现的向量化运算,速度远快于Python层级的循环
内容的提问来源于stack exchange,提问作者Sultanust
相关产品推荐
相关产品推荐

