Python解析CSV中超23:59的时间值及日期调整方案
解析含超23:59时间值的CSV日期时间列,自动调整日期
问题场景
现有CSV文件包含以下列(均为未转换的object类型):
- 日期列:格式为
月/日/年(如1/1/2000) - 开始时间、结束时间列:多数值为
小时:分钟格式,但存在部分超过23:59的异常值,这类值格式为小时:分钟:秒(如24:50:00、25:35:00)
使用以下代码解析时触发报错:
time_parser = lambda x: pd.datetime.strptime(x, '%H:%M') df = pd.read_csv('data.csv', parse_dates = ['StartTime'], date_parser = time_parser)
报错信息:25:39 does not match format %H:%M
需求
- 正确解析存在异常时间值的时间列
- 若开始时间超过23:59,自动根据超时时长调整对应日期(例如
1/1/2000对应24:50:00时,最终日期时间应为1/2/2000 00:50:00) - 明确结束时间列的合理处理方式
解决方案
核心思路:先将日期解析为基础日期,再将时间字符串转换为时间差(Timedelta),通过日期+时间差的方式自动处理跨天情况,避免手动判断小时数的复杂逻辑。
步骤1:读取原始CSV
先不提前解析日期时间,保留原始字符串以便后续处理:
import pandas as pd df = pd.read_csv('data.csv')
步骤2:编写通用日期时间合并函数
该函数可兼容两种时间格式,自动计算跨天的最终日期时间:
def parse_time_with_date(date_str, time_str): # 解析基础日期(月/日/年格式) base_date = pd.to_datetime(date_str, format='%m/%d/%Y') # 处理时间字符串,转换为Timedelta try: parts = time_str.split(':') if len(parts) == 2: hours, minutes = map(int, parts) time_delta = pd.Timedelta(hours=hours, minutes=minutes) elif len(parts) == 3: hours, minutes, seconds = map(int, parts) time_delta = pd.Timedelta(hours=hours, minutes=minutes, seconds=seconds) else: return pd.NaT # 异常格式返回空值 except (ValueError, AttributeError): return pd.NaT # 解析失败返回空值 # 合并日期与时间差,自动处理跨天 return base_date + time_delta
步骤3:处理开始时间列
调用函数合并日期列与开始时间列,得到正确的datetime类型值:
# 替换成你的日期列实际名称,比如'Date' df['StartTime'] = df.apply(lambda row: parse_time_with_date(row['Date'], row['StartTime']), axis=1)
步骤4:处理结束时间列
根据业务场景选择以下两种方式之一:
场景A:结束时间是基于原始日期的时间点
即使开始时间跨天,结束时间仍按原始日期计算,自动调整跨天情况:
df['EndTime'] = df.apply(lambda row: parse_time_with_date(row['Date'], row['EndTime']), axis=1)
场景B:结束时间是相对于开始时间的时长
如果结束时间代表的是从开始时间起的持续时长(而非当天的时间点),先将结束时间转为时间差,再与调整后的开始时间相加:
def parse_to_timedelta(time_str): try: parts = time_str.split(':') if len(parts) == 2: hours, minutes = map(int, parts) return pd.Timedelta(hours=hours, minutes=minutes) elif len(parts) == 3: hours, minutes, seconds = map(int, parts) return pd.Timedelta(hours=hours, minutes=minutes, seconds=seconds) else: return pd.NaT except (ValueError, AttributeError): return pd.NaT df['EndTime'] = df['StartTime'] + df['EndTime'].apply(parse_to_timedelta)
原代码报错原因
%H格式符仅支持0-23的小时数,无法解析超过23的小时值;而使用Timedelta可以直接将任意小时数转换为时间差,与基础日期相加后自动处理日期进位,无需额外判断逻辑。
内容的提问来源于stack exchange,提问作者Eggy
相关产品推荐
相关产品推荐

