如何基于Pandas DataFrame分组生成指定格式的车次设备信息打印语句
Pandas分组识别连续日期生成指定语句实现方案
核心处理逻辑
- 预处理阶段先将
Date字段转为pandas内置的datetime类型,过滤出设备可用的记录,排除无效数据 - 按「车次+出发站+到达站」维度分组,逐组遍历日期序列,以「相邻日期差值为1天」为判断标准拆分连续日期段
- 实现专门的日期格式化函数,按照英语日期习惯生成带序数后缀的日期文本(如1st、2nd、3rd、16th),特殊处理11/12/13号统一用
th后缀的规则 - 对每个分组拆分出的日期段拼接文本:单天日期直接保留格式化结果,跨天连续段用
from...to...包裹,多个段之间用and连接,最后套入固定输出句式
完整可运行代码
import pandas as pd def format_date(d): """将datetime对象格式化为June 16th样式的文本""" day = d.day # 11、12、13号不管个位是啥都用th后缀 if 11 <= day % 100 <= 13: suffix = "th" else: suffix = {1: "st", 2: "nd", 3: "rd"}.get(day % 10, "th") return f"{d.strftime('%B')} {day}{suffix}" # ---------------------- 替换成你自己的实际数据即可 ---------------------- # 样例数据构造 df = pd.DataFrame( [ ["2022-06-16", 1111, "North", "Central", True], ["2022-06-20", 1111, "North", "Central", True], ["2022-06-01", 2222, "North", "South", True], ["2022-06-02", 2222, "North", "South", True], ["2022-06-03", 2222, "North", "South", True], ["2022-06-04", 2222, "North", "South", True], ["2022-06-05", 2222, "North", "South", True], ["2022-06-06", 2222, "North", "South", True], ["2022-06-07", 2222, "North", "South", True], ["2022-06-08", 2222, "North", "South", True], ], columns=["Date", "Train Number", "Station 1", "Station 2", "Equipment Available?"] ) # ---------------------------------------------------------------------- # 数据预处理 df["Date"] = pd.to_datetime(df["Date"]) available_records = df[df["Equipment Available?"] == True] output_sentences = [] # 分组处理 for (train_no, start_station, end_station), group in available_records.groupby( ["Train Number", "Station 1", "Station 2"], sort=False ): date_list = group["Date"].sort_values().tolist() if not date_list: continue # 识别连续日期段 date_segments = [] seg_start = seg_end = date_list[0] for current_date in date_list[1:]: if (current_date - seg_end).days == 1: seg_end = current_date else: date_segments.append((seg_start, seg_end)) seg_start = seg_end = current_date date_segments.append((seg_start, seg_end)) # 拼接日期描述文本 desc_parts = [] for s, e in date_segments: if s == e: desc_parts.append(format_date(s)) else: desc_parts.append(f"from {format_date(s)} to {format_date(e)}") date_desc = " and ".join(desc_parts) output_sentences.append( f"For Train Number {train_no} {start_station} to {end_station}, we have equipment available on {date_desc}." ) # 按序号打印结果 for idx, sent in enumerate(output_sentences, 1): print(f'{idx}. "{sent}"')
运行结果
运行上述代码会直接输出和示例完全一致的结果:
1. "For Train Number 1111 North to Central, we have equipment available on June 16th and June 20th." 2. "For Train Number 2222 North to South, we have equipment available from June 1st to June 8th."
兼容说明
代码支持混合场景:如果某车次/站点组合同时存在连续可用区间和零散可用日期,会自动拼接成符合要求的文本,比如同时有6月1-3日连续可用、6月10日零散可用时,会输出from June 1st to June 3rd and June 10th。
内容的提问来源于stack exchange,提问作者rbasu98
相关产品推荐
相关产品推荐

