含NaN的日期列用列表推导式计算工作日差报错如何解决
错误原因
- 条件判断逻辑无效:原代码中
if (x,y) != np.isnan的写法完全不生效,np.isnan是用于判断NaN的函数,不是NaN值本身,且NaN不能直接用==/!=判断(NaN与任何值比较都返回False,包括它自身)。 - 列表推导式语法错误:仅写在
for循环后的if是过滤条件,会剔除不符合条件的元素,最终生成的列表长度会短于原DataFrame行数,直接赋值给新列会触发长度不匹配错误,需要用三元表达式为不符合条件的元素返回0,保证输出长度和原表一致。 - 日期格式不规范:原始日期列是字符串类型,空值为
np.nan,直接传入pd.bdate_range易被识别为无效值,建议先转为pandas datetime类型,空值会自动转为NaT更便于空值判断。
解决方案
前置处理:统一日期格式
首先将两列日期转为pandas datetime类型:
import pandas as pd import numpy as np data = pd.DataFrame({ 'date1' : [np.nan, np.nan, "2021-05-26", "2021-06-25", "2021-06-30"], 'date2' : [np.nan, np.nan, "2021-06-30", "2021-06-28", "2021-06-30"] }) # 转datetime类型,空值自动转为NaT data['date1'] = pd.to_datetime(data['date1']) data['date2'] = pd.to_datetime(data['date2'])
方法1:修正列表推导式
调整三元表达式的位置,用pd.isna()统一判断NaN/NaT空值:
data["delay"] = [len(pd.bdate_range(x, y)) if not pd.isna(x) and not pd.isna(y) else 0 for x, y in zip(data.date1, data.date2)]
方法2:使用apply方法(可读性更高)
自定义计算函数通过行遍历实现:
def calc_business_delay(row): # 任意一列为空则返回0 if pd.isna(row['date1']) or pd.isna(row['date2']): return 0 # 计算工作日数量,包含首尾日期 return len(pd.bdate_range(row['date1'], row['date2'])) data['delay'] = data.apply(calc_business_delay, axis=1)
运行结果
最终得到的DataFrame如下:
>>> data date1 date2 delay 0 NaT NaT 0 1 NaT NaT 0 2 2021-05-26 2021-06-30 25 3 2021-06-25 2021-06-28 2 4 2021-06-30 2021-06-30 1
如果需要计算不含首日的间隔天数,将len(pd.bdate_range(...))的结果减1即可。
内容的提问来源于stack exchange,提问作者SachaL
相关产品推荐
相关产品推荐

