逐行比较DATETIME列并替换为1/0,寻求性能优化方案
Pandas 日期比较性能优化:替代逐行循环实现100+列的日期判断
问题背景
需要将UTIL_DATE列与另外100个日期列逐行比较:
- 若
UTIL_DATE日期≥目标列日期,对应值设为1 - 否则设为0,目标列含
NaT时同样设为0
原代码用iterrows逐行循环+try-except处理异常,耗时超1.5小时,急需性能优化。原代码片段:
for idx, row in df.iterrows(): # row is each row in df and idx is the index for each row for i in format_cols: # format_cols is the list of columns to be compared with the UTIL_DATE column ifor_val = 0 # taking ifor_val as 0 by default try: if (pd.to_datetime(row["Util_Date"]) >= pd.to_datetime(row[i])): ifor_val = 1 # if Util_Date >= column "i" date, then map it to 1. Else 0 except: ifor_val = 0 df.loc[idx,i]=ifor_val
原代码性能瓶颈
iterrows是逐行Python级迭代,远慢于Pandas底层的向量化操作- 每行重复调用
pd.to_datetime,存在大量冗余计算 df.loc[idx,i]逐元素赋值,IO开销极大- 全局
try-except捕获所有异常,额外增加运行成本
优化方案:向量化操作替代循环
直接利用Pandas的广播特性和向量化函数,一次性完成所有列的比较和赋值,速度提升几个数量级:
# 1. 统一转换日期类型(若列已是datetime可跳过此步) df["Util_Date"] = pd.to_datetime(df["Util_Date"], errors="coerce") df[format_cols] = df[format_cols].apply(pd.to_datetime, errors="coerce") # 2. 向量化比较并生成结果 df[format_cols] = (df["Util_Date"].values[:, None] >= df[format_cols]).astype(int)
代码说明
errors="coerce":将无效日期字符串直接转为NaT,避免异常处理df["Util_Date"].values[:, None]:将单列转为二维数组,实现与多列的广播比较- 布尔值转
int:True自动转1,False(包括NaT比较结果)自动转0,完全符合需求
效果
原本小时级的运行时间会压缩到秒级,同时逻辑更简洁,避免了循环带来的潜在bug。
内容的提问来源于stack exchange,提问作者Neeraj Khadagade
相关产品推荐
相关产品推荐

