Python pandas如何处理不一致日期序列转换时的日月混淆问题?
混合日期格式解析错位、入住夜数计算为负的解决方案

问题根因
pd.to_datetime默认的自动格式推断逻辑,无法适配同一列内混杂DD/MM/YYYY、MM/DD/YYYY两种日期格式的场景:
- 当日、月位置的数值都≤12时,解析器会按默认优先级统一识别,直接造成日月错位
- 当日位置数值>12时,按
MM/DD/YYYY规则解析会直接判定为无效值返回NaT
错位的日期做差后,自然会出现入住夜数为负的异常结果。
可直接落地的解决步骤
1. 编写适配混合格式的日期解析函数
不需要手动拆分拼接年月日字段,通过逐单元格格式匹配完成初步解析:
import pandas as pd from datetime import datetime def parse_mixed_date(date_val): if pd.isna(date_val): return pd.NaT date_str = str(date_val).strip() # 按优先级匹配格式,可根据数据集实际格式补充fmt列表内容 for fmt in ['%d/%m/%Y', '%m/%d/%Y']: try: return datetime.strptime(date_str, fmt) except ValueError: continue return pd.NaT
2. 初步转换两列日期
df['Check-in date'] = df['Check-in date'].apply(parse_mixed_date) df['Check-out date'] = df['Check-out date'].apply(parse_mixed_date)
3. 结合业务规则修正歧义日期
对于日月数值都≤12的歧义日期,用「入住日期必须早于退房日期」的业务逻辑做二次校验,自动修正错位的记录:
# 标记日期差为负的异常记录 abnormal_mask = (df['Check-out date'] - df['Check-in date']).dt.days < 0 # 对异常记录互换日月位置修正 def swap_day_month(dt): return pd.NaT if pd.isna(dt) else dt.replace(day=dt.month, month=dt.day) df.loc[abnormal_mask, ['Check-in date', 'Check-out date']] = df.loc[abnormal_mask, ['Check-in date', 'Check-out date']].applymap(swap_day_month)
4. 计算入住夜数
df['stay_nights'] = (df['Check-out date'] - df['Check-in date']).dt.days
校验提示
- 计算完成后可以通过
df['stay_nights'].describe()查看结果分布,如果仍存在负值,可通过df[df['stay_nights'] < 0]筛出对应记录,排查是否存在原始数据录入错误(如退房日期真实早于入住日期的异常订单)。 - 如果数据集内还存在横杠、点分隔的其他日期格式,只要在
parse_mixed_date函数的fmt列表中补充对应的格式串即可,比如添加'%d-%m-%Y'适配20-05-2024这类格式。
内容的提问来源于stack exchange,提问作者Dan Balictar
相关产品推荐
相关产品推荐

