如何自动计算多组全局DataFrame的区域平方差并筛选最小值?
解决方案:自动化计算平方距离最小值 + 全局变量实践分析
一、全局变量的问题与替代方案
直接用全局变量存储forecast_Hour_XX和Pool_Hour_XX这类DataFrame属于不良实践,核心问题包括:
- 命名冲突:新增变量时容易覆盖现有数据,引发难以排查的错误。
- 可读性差:无法直观知道有多少个这类数据集,也难以梳理它们的关联。
- 维护困难:全局变量的修改轨迹难以追踪,调试成本高。
- 扩展性弱:小时数或历史池数量变化时,硬编码处理会非常繁琐。
替代方案:用字典统一管理这些DataFrame,无论是生成时直接存入字典,还是从全局变量中批量提取,都能大幅提升代码的可维护性:
# 从全局变量中批量提取预测数据(如果已经生成了全局变量) forecasts = { hour_key: globals()[hour_key] for hour_key in [f"forecast_Hour_{i:02d}" for i in range(1, 25)] } # 批量提取历史池数据(匹配命名规则) pools = { pool_key: df for pool_key, df in globals().items() if pool_key.startswith("Pool_Hour_") }
二、自动化计算平方距离并筛选最小值
1. 定义平方差求和函数
先写一个函数,专门处理单个预测DataFrame和历史池DataFrame的平方差求和逻辑:
import pandas as pd def calculate_total_squared_diff(forecast_df, pool_df): # 按BZ区域合并两个数据集,只保留需要的列 merged_data = forecast_df[["BZ", "Value"]].merge( pool_df[["BZ", "Value"]], on="BZ", suffixes=("_forecast", "_pool") ) # 计算每个区域的平方差并求和 merged_data["squared_diff"] = (merged_data["Value_forecast"] - merged_data["Value_pool"]) ** 2 return merged_data["squared_diff"].sum()
2. 遍历所有组合并计算结果
遍历每个小时的预测数据,匹配对应小时的历史池数据,计算平方差和并存储结果:
results_list = [] for forecast_name, forecast_df in forecasts.items(): # 提取当前小时(比如从"forecast_Hour_03"中提取"03") current_hour = forecast_name.split("_")[-1] # 筛选对应小时的历史池数据 matching_pools = { name: df for name, df in pools.items() if name.endswith(current_hour) } # 遍历匹配的历史池计算 for pool_name, pool_df in matching_pools.items(): total_diff = calculate_total_squared_diff(forecast_df, pool_df) results_list.append({ "hour": current_hour, "forecast_dataset": forecast_name, "pool_dataset": pool_name, "total_squared_distance": total_diff }) # 转换为结果DataFrame results_df = pd.DataFrame(results_list)
3. 筛选最小值
从结果DataFrame中找出平方距离最小的记录:
# 找到最小平方距离对应的行 min_result = results_df.loc[results_df["total_squared_distance"].idxmin()] # 输出结果 print(f"最小平方距离出现在小时{min_result['hour']}") print(f"对应组合:{min_result['forecast_dataset']} vs {min_result['pool_dataset']}") print(f"平方距离总和:{min_result['total_squared_distance']:.2f}")
三、优化建议
如果还没生成那些全局变量,建议在生成DataFrame时直接存入字典,比如:
# 示例:生成预测数据时直接存入字典 forecasts = {} for hour in range(1, 25): hour_str = f"{hour:02d}" # 假设这里是生成forecast_Hour_XX的逻辑 forecasts[f"forecast_Hour_{hour_str}"] = your_generation_logic(hour_str) # 历史池数据同理 pools = {} # 假设这里是生成Pool_Hour_XX的循环逻辑 for pool_hour in your_pool_hours: pools[f"Pool_Hour_{pool_hour}"] = your_pool_generation_logic(pool_hour)
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

