如何以Pythonic方式通过切片现有DataFrame创建新DataFrame?
高效自动切片时序数据方案需求
我手里有个包含约600万条时序数据的Pandas DataFrame,数据覆盖多种BZ类型、全年连续时段。目前已经筛选出Horizon为'D-2'的预测数据,但一直是手动硬编码按EvaluationUtc时段生成切片DataFrame,想找个高效的自动实现方法。
示例代码与数据
构建示例DataFrame的代码:
import pandas as pd begin = pd.to_datetime('2023-01-01 00:00:00') end = pd.to_datetime('2023-01-01 05:00:00') df = pd.DataFrame(columns = ['EvaluationUtc','Horizon','type','BZ','Value']) A = pd.date_range(start= begin, end= end, periods=5) B = ['D-2','D-1','D-1','D-1','Selected'] C = ['ND','ND','ND','ND','ND'] D = ['NO1','NO1','NO1','NO1','NO1'] E = [1568,1324,5678,4321,4564] df.EvaluationUtc = A df.Horizon = B df.type = C df.BZ = D df.Value = E
筛选预测数据的代码:
forecast = df[(df['Horizon']== 'D-2') ] forecast.reset_index(drop = True, inplace = True)
手动生成切片的示例代码:
from datetime import timedelta forecast_Hour_1 = forecast[(forecast['EvaluationUtc'] == begin)].reset_index(drop = True) forecast_Hour_2 = forecast[(forecast['EvaluationUtc'] == begin + timedelta(hours=1))].reset_index(drop = True) ...
解决方案
方法1:用groupby生成切片字典(推荐)
这是最高效且易维护的方案,把每个EvaluationUtc对应的切片存入字典,键可以直接用时间戳或格式化字符串,后续调用非常方便:
from datetime import timedelta # 先筛选目标数据(如果还没做的话) forecast = df[df['Horizon'] == 'D-2'].reset_index(drop=True) # 按EvaluationUtc分组,自动生成所有切片的字典 forecast_slices = {time: group.reset_index(drop=True) for time, group in forecast.groupby('EvaluationUtc')} # 调用示例:获取指定时段的切片 forecast_Hour_1 = forecast_slices[begin] forecast_Hour_2 = forecast_slices[begin + timedelta(hours=1)] # 批量处理所有切片示例 for time, slice_df in forecast_slices.items(): # 在这里对每个切片做后续操作,比如计算、导出等 print(f"处理时段:{time},数据量:{len(slice_df)}")
优势
- 完全自动遍历所有唯一的EvaluationUtc,无需手动硬编码
- 字典查询速度极快,适配600万条数据的大数据场景
- 便于批量处理所有切片,扩展性强
方法2:动态生成独立变量(不推荐,仅作参考)
如果一定要生成forecast_Hour_1这类独立变量,可以用动态命名的方式,但这种方式会让代码可读性变差,不利于维护,仅适合特殊场景:
# 获取所有唯一的EvaluationUtc并按时间排序 unique_times = sorted(forecast['EvaluationUtc'].unique()) # 动态生成变量 for idx, time in enumerate(unique_times, start=1): globals()[f'forecast_Hour_{idx}'] = forecast[forecast['EvaluationUtc'] == time].reset_index(drop=True)
针对大数据量的性能优化
- 设置索引加速:给
EvaluationUtc列设置索引,后续切片速度会大幅提升forecast.set_index('EvaluationUtc', inplace=True) # 之后直接用loc切片 forecast_Hour_1 = forecast.loc[begin].reset_index(drop=True) - 避免重复计算:尽量一次性完成筛选和分组,不要多次对原DataFrame做布尔索引
- 优先用视图而非副本:如果不需要修改切片数据,可以考虑用
df.loc生成视图(但Pandas在很多场景下会自动生成副本,groupby的方式已经是高效的分组处理)
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

