如何进一步优化Pandas中基于多列的条件列创建代码?
Pandas多条件生成新列的性能优化方案
针对你2万行DataFrame、基于4列10多个条件生成新列的场景,给你几个比当前itertuples+cache更高效的优化方向:
1. 跳过手动列转元组,直接利用itertuples原生属性
你现在手动把列分组为元组再传给缓存函数,其实完全没必要——itertuples返回的namedtuple可以直接通过属性名提取列值,直接把这些值作为缓存函数的参数即可,省去手动打包元组的步骤:
from functools import cache @cache def calculate_new_val(col1, col2, col3, col4): # 这里写你的10多个条件判断逻辑 if col1 > 10 and col2 == "A": return 1 elif col3 <= 5 and col4 in ("X", "Y"): return 2 # ... 其他条件 return 0 df['new_col'] = [calculate_new_val(row.col1, row.col2, row.col3, row.col4) for row in df.itertuples()]
单个基本类型(数值、字符串)本身就是可哈希的,直接作为cache的参数比手动转元组更高效,还能减少代码冗余。
2. 先计算唯一列组合结果,再映射回原表(大幅减少计算次数)
2万行数据中,4列的组合大概率有大量重复。你可以先提取这些列的唯一组合,只计算一次每个组合的结果,再映射回原DataFrame,彻底减少计算量:
# 提取4列的唯一组合 unique_groups = df[["col1", "col2", "col3", "col4"]].drop_duplicates() # 给每个唯一组合计算结果 def get_result(row): # 你的条件逻辑 if row.col1 > 10 and row.col2 == "A": return 1 # ... 其他条件 return 0 unique_groups['new_col'] = unique_groups.apply(get_result, axis=1) # 把结果映射回原表 df = df.merge(unique_groups, on=["col1", "col2", "col3", "col4"], how="left")
这种方法的计算次数等于唯一组合的数量,远小于2万次,性能提升非常明显。如果你的条件逻辑可以改成向量化判断,还能把apply换成更快的向量化操作。
3. 用Pandas向量化操作替代迭代(最优性能方案)
Pandas的核心优势是向量化操作,完全跳过逐行迭代和缓存,直接用布尔掩码批量处理,速度比itertuples快几个数量级。即使条件多,也可以把条件整理成列表批量处理,避免多行.loc的繁琐:
# 初始化新列 df['new_col'] = 0 # 把所有条件和对应值整理成列表 condition_list = [ ((df['col1'] > 10) & (df['col2'] == "A"), 1), ((df['col3'] <= 5) & (df['col4'].isin(["X", "Y"])), 2), ((df['col1'] <= 5) & (df['col3'] > 20), 3), # ... 其他条件和对应结果 ] # 批量应用条件 for mask, value in condition_list: df.loc[mask, 'new_col'] = value
这种方式不需要任何缓存或元组转换,完全利用Pandas的底层优化,是处理这类场景的最优解。
内容的提问来源于stack exchange,提问作者Tiago Iesbick
相关产品推荐
相关产品推荐

