如何使用Python或SQL为每个路由生成等长日历日数据行?
没问题,这个需求我帮你搞定!下面分别给出Python(基于pandas库)和SQL两种实现方案,你可以根据自己的技术栈来选~
Python 实现方案(基于pandas)
如果你习惯用Python处理数据,pandas是个很方便的选择,步骤如下:
- 准备原始数据:先把你的数据转换成pandas DataFrame(如果是从文件读取的话用
pd.read_csv()之类的方法就行)。 - 计算每个路由的最大天数:用分组聚合拿到每个路由对应的最大需求天数。
- 生成连续日历日序列:遍历每个路由,生成从1到最大天数的所有连续日期。
- 匹配原始需求数据:通过左连接把原始的demand-days匹配到对应的日历日,没有匹配到的就会自动留空。
完整代码示例:
import pandas as pd # 模拟原始数据(实际使用时可以替换成读取文件的代码) raw_data = pd.DataFrame({ 'routes': ['Paris-New York', 'Paris-New York', 'Paris-New York', 'London-Berlin', 'London-Berlin', 'London-Berlin', 'London-Berlin', 'Tokyo-Shanghai', 'Tokyo-Shanghai'], 'demand-days': [1, 3, 5, 2, 3, 4, 5, 2, 4] }) # 1. 获取每个路由的最大需求天数 max_days = raw_data.groupby('routes')['demand-days'].max().reset_index(name='max_day') # 2. 生成每个路由的连续日历日 calendar_list = [] for _, row in max_days.iterrows(): route_name = row['routes'] end_day = row['max_day'] # 生成1到end_day的所有天数,和路由配对 calendar_list.extend([(route_name, day) for day in range(1, end_day + 1)]) calendar_df = pd.DataFrame(calendar_list, columns=['routes', 'calendar days']) # 3. 左连接匹配原始数据,得到最终结果 final_result = pd.merge( calendar_df, raw_data, left_on=['routes', 'calendar days'], right_on=['routes', 'demand-days'], how='left' ).drop(columns='demand-days_y').rename(columns={'demand-days_x': 'demand-days'}) # 可选:把NaN替换为空字符串,方便导出 final_result['demand-days'] = final_result['demand-days'].fillna('') # 打印结果 print(final_result)
SQL 实现方案
如果你的数据存在数据库里,用SQL直接处理更高效,下面分两种常见数据库给出实现:
MySQL 版本(8.0+ 支持递归CTE)
-- 先定义CTE获取每个路由的最大天数 WITH route_max_days AS ( SELECT routes, MAX(`demand-days`) AS max_day FROM original_table -- 替换成你的实际表名 GROUP BY routes ), -- 递归生成每个路由的连续日历日 calendar_series AS ( SELECT routes, 1 AS `calendar days` FROM route_max_days UNION ALL SELECT r.routes, c.`calendar days` + 1 FROM calendar_series c JOIN route_max_days r ON c.routes = r.routes WHERE c.`calendar days` + 1 <= r.max_day ) -- 左连接原始表匹配需求天数 SELECT cs.routes, cs.`calendar days`, ot.`demand-days` FROM calendar_series cs LEFT JOIN original_table ot ON cs.routes = ot.routes AND cs.`calendar days` = ot.`demand-days` ORDER BY cs.routes, cs.`calendar days`;
PostgreSQL 版本(用generate_series简化序列生成)
WITH route_max_days AS ( SELECT routes, MAX("demand-days") AS max_day FROM original_table -- 替换成你的实际表名 GROUP BY routes ) SELECT r.routes, s.day AS "calendar days", ot."demand-days" FROM route_max_days r -- 用LATERAL关联生成每个路由的连续天数 LATERAL generate_series(1, r.max_day) AS s(day) LEFT JOIN original_table ot ON r.routes = ot.routes AND s.day = ot."demand-days" ORDER BY r.routes, s.day;
运行后,没有匹配到demand-days的行会显示为NULL,大部分可视化工具导出时会自动转成空字符串。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

