基于多年15分钟时间序列数据生成跨年月组合子集的技术咨询
问题需求
我拥有2007-2022年共16年的15分钟间隔时间序列数据,需要从这些数据中生成所有可能的子集,每个子集对应一整年的数据量:
- 平年:4(15分钟间隔)×24(小时)×365 = 35040行
- 闰年:4×24×366 = 35136行
子集需满足以下要求:
- 由12个月份的数据组成,每个月份对应1-12月中的一个,且每个月份的所有15分钟数据必须完整连续纳入子集
- 每个月份的数据可来自任意年份,允许子集包含同一年份的多个月份
已完成的数据读取代码
import pandas as pd import numpy as np columns_to_read = ['DateTime', 'PLANT ENERGY MWh'] df = pd.read_excel(r'C:/Users/97150/Data - 15 mins multiyear -R2.xlsx', skiprows=0, usecols=columns_to_read) df['DateTime'] = pd.to_datetime(df['DateTime']) df.dropna(subset=['DateTime'], inplace=True) df['Month'] = df['DateTime'].dt.month.astype(int) df['Year'] = df['DateTime'].dt.year.astype(int) df.set_index('DateTime', inplace=True)
后续实现步骤与代码示例
1. 验证每个(年,月)组合的数据完整性
首先筛选出所有数据完整的月份,只有完整的月份才能被纳入子集:
# 计算每个(年,月)的理论行数 def get_expected_rows(year, month): if month in [4,6,9,11]: return 4*24*30 # 小月30天 elif month == 2: if pd.Timestamp(year=year, month=1, day=1).is_leap_year: return 4*24*29 # 闰年2月 else: return 4*24*28 # 平年2月 else: return 4*24*31 # 大月31天 # 统计每个(年,月)的实际行数 monthly_row_counts = df.groupby(['Year', 'Month']).size().reset_index(name='ActualRows') # 筛选出数据完整的月份 monthly_row_counts['ExpectedRows'] = monthly_row_counts.apply( lambda x: get_expected_rows(x['Year'], x['Month']), axis=1 ) complete_months = monthly_row_counts[monthly_row_counts['ActualRows'] == monthly_row_counts['ExpectedRows']] # 整理为字典:key=月份,value=该月份数据完整的年份列表 valid_year_per_month = complete_months.groupby('Month')['Year'].apply(list).to_dict()
2. 生成所有可能的12个月组合
用itertools.product生成所有符合要求的年份组合,每个组合对应1-12月各选一个数据完整的年份:
import itertools # 按1-12月顺序获取各月的有效年份列表 month_order = range(1,13) valid_year_lists = [valid_year_per_month[month] for month in month_order] # 生成所有可能的年份组合,每个元素格式为(1月年份, 2月年份, ..., 12月年份) all_combinations = list(itertools.product(*valid_year_lists))
3. 提取并保存每个子集
遍历所有组合,提取对应月份的数据并合并成子集,按需保存:
import os # 创建子集保存目录 output_dir = 'annual_subsets' os.makedirs(output_dir, exist_ok=True) for idx, combo in enumerate(all_combinations): subset_dfs = [] # 提取组合中每个(月份,年份)对应的数据 for month, year in zip(month_order, combo): monthly_data = df[(df['Year'] == year) & (df['Month'] == month)] subset_dfs.append(monthly_data) # 合并为完整子集 annual_subset = pd.concat(subset_dfs).reset_index() # 生成文件名并保存 combo_str = '-'.join(map(str, combo)) output_path = os.path.join(output_dir, f'subset_{idx+1:04d}_{combo_str}.csv') annual_subset.to_csv(output_path, index=False) print(f"已生成子集: {output_path}")
注意事项
- 若某个月份无完整数据,需先检查原始数据完整性,补充缺失数据或调整需求
- 组合数量可能极大(如每个月有16个可选年份时,总组合数达16^12≈1.8e14),实际运行建议抽样或限制年份范围以避免资源耗尽
- 可修改保存格式(如Excel),或合并后验证子集总行数是否符合平年/闰年要求
内容的提问来源于stack exchange,提问作者Jawairia
相关产品推荐
相关产品推荐

