pandas中如何基于时间仅修改同ID同列车分组的跨零点行日期
需求实现可行性说明
该需求完全可以通过pandas的分组遍历逻辑实现,无需依赖外部工具,且能100%匹配你给出的期望输出规则。
核心实现逻辑
按照你提出的规则,处理逻辑拆解为:
- 分组维度:严格按照
ID和Train的取值划分同一条列车线路的记录组 - 跨天判断:组内按照表格原有的站序逐行对比时间,若当前行的时间早于上一行的时间(说明时间跨过了24:00零点),则将该行及后续所有同组记录的日期整体向后顺延1天
- 特殊边界:每组的第一行记录默认保留原始日期,哪怕时间落在零点后(对应你示例中ICE-342组Wien站00:35的记录不调整日期的规则)
完整可运行代码
import pandas as pd # ---------------------- # 1. 数据预处理 # ---------------------- # 替换为你实际的DataFrame读取逻辑 df = pd.read_clipboard() # 将原始日期字符串(日.月.年格式)转为可计算的datetime类型 df['Date'] = pd.to_datetime(df['Date'], format='%d.%m.%Y') # 将时分格式的时间转为当日累计分钟数,用于跨天先后对比 df['Time_min'] = df['Time'].apply(lambda x: int(x.split(':')[0]) * 60 + int(x.split(':')[1])) # ---------------------- # 2. 定义分组内跨天调整的处理函数 # ---------------------- def adjust_group_date(group): total_offset = 0 # 累计需要加的天数 last_time = None # 记录上一行的时间分钟值 adjusted_date_list = [] for _, row in group.iterrows(): # 跳过组内第一行的跨天判断 if last_time is not None: # 当前时间早于上一行时间,判定为跨零点,天数偏移+1 if row['Time_min'] < last_time: total_offset += 1 # 计算当前行调整后的日期 adjusted_date = row['Date'] + pd.Timedelta(days=total_offset) adjusted_date_list.append(adjusted_date) # 更新上一行的时间记录 last_time = row['Time_min'] group['Adjusted_Date'] = adjusted_date_list return group # ---------------------- # 3. 分组应用规则、整理输出格式 # ---------------------- # 按ID和Train分组应用调整逻辑 df = df.groupby(['ID', 'Train'], group_keys=False).apply(adjust_group_date) # 将调整后的日期替换原Date列,转回原始的字符串格式 df['Date'] = df['Adjusted_Date'].dt.strftime('%d.%m.%Y') # 删除临时辅助列 df = df.drop(columns=['Time_min', 'Adjusted_Date'])
注意事项
- 代码默认你当前DataFrame的行顺序就是列车的实际运行站序(从上到下对应从始发站到终点站的顺序),如果行序混乱,需要先按组内的站序排序后再执行调整逻辑,否则跨天判断会出错
- 对于运行时长超过24小时、存在多次跨零点的长距离列车,代码会自动累计对应顺延的天数,无需额外修改逻辑
内容的提问来源于stack exchange,提问作者user14976825
相关产品推荐
相关产品推荐

