如何让Pandas兼容360天日历?解析含2月30日的CSV日期
Pandas解析含360天日历日期CSV的解决方案
方案一:自定义解析函数,兼容多日历类型
直接用to_datetime会因为2月30这类360天日历的日期报错,我们可以先把日期列读成字符串,再写个自定义函数兼容常规日历和360天日历的解析:
import pandas as pd from datetime import datetime def parse_dates(date_str): try: # 先按常规日历解析 return datetime.strptime(date_str, '%Y-%m-%d') except ValueError: # 捕获"day out of range"异常,处理360天日历的特殊日期 year, month, day = map(int, date_str.split('-')) # 针对2月30日这类情况,按业务需求转换(比如转成3月2日,或保留原字符串) if month == 2 and day == 30: return datetime(year, 3, 2) # 其他超过当月天数的日期(比如4月31日),统一转成下月对应天数 elif day > 30: return datetime(year, month + 1, day - 30) # 其他无法解析的情况返回NaT return pd.NaT # 读取CSV时先把日期列设为字符串类型 df = pd.read_csv('your_data.csv', dtype={'date_col': str}) # 应用自定义解析函数 df['date_col'] = df['date_col'].apply(parse_dates)
方案二:先保留原始字符串,按需分类型处理
如果不需要立刻转成datetime,可以用errors='ignore'让Pandas保留原始日期字符串,之后根据日历类型分开处理:
# 读取时不强制解析日期,保留字符串 df = pd.read_csv('your_data.csv', parse_dates=['date_col'], errors='ignore') # 后续筛选出360天日历的特殊日期单独处理 special_dates = df[df['date_col'].str.match(r'\d{4}-02-30')] # 对这些日期执行自定义转换逻辑,比如替换为合法日期或标记
方案三:用数值映射处理360天日历
如果需要对360天日历做日期运算,可以把日期转换成累计天数,再转成numpy的datetime64:
import numpy as np def convert_360_calendar(date_str): year, month, day = map(int, date_str.split('-')) # 计算360天日历下的累计天数(从0001年1月1日开始) total_days = (year - 1)*360 + (month - 1)*30 + day # 转成numpy datetime64 return np.datetime64('0001-01-01') + np.timedelta64(total_days - 1, 'D') # 给360天日历的日期单独列转换 df['360_date'] = df['date_col'].apply(convert_360_calendar)
注意事项
- 自定义转换逻辑要和你的业务需求匹配,比如2月30日是转成3月2日还是保留原字符串,完全看业务场景。
- 如果要同时处理多种日历,建议加个标记列(比如
calendar_type),或者通过日期特征自动判断,针对性应用解析逻辑。 - 别直接用
errors='coerce',会直接把异常日期转成NaT,丢失原始数据。
内容的提问来源于stack exchange,提问作者Thomas Kroißenbrunner
相关产品推荐
相关产品推荐

