如何在pandas多级索引DataFrame中查询指定参数的插值数据?
多级索引DataFrame的二维插值查询
问题背景
已创建如下多级索引的Pandas DataFrame,需查询GEN PF=0.9769、Generator power at terminal, (kW)=736381.3时的插值结果,尝试df.loc仅能查询已有数据,无法实现二维插值且触发Key Error:
import pandas as pd GEN_power_vs_PF_index = pd.MultiIndex.from_tuples([('GEN PF', '0.85'), ('GEN PF', '0.9'), ('GEN PF', '0.95'), ('GEN PF', '1.0')]) GEN_power_vs_PF_columns = pd.MultiIndex.from_tuples([('Generator power at terminal, (kW)', 201875), ('Generator power at terminal, (kW)', 403750), ('Generator power at terminal, (kW)', 605625), ('Generator power at terminal, (kW)', 807500), ('Generator power at terminal, (kW)', 1009375)]) GEN_power_vs_PF = pd.DataFrame([(3217.6, 4259.1, 5847, 8024.1, 11059.1), (3133.2, 4023, 5390.5, 7242.6, 9678.4), (3045.4, 3791.7, 4954.4, 6538.8, 8564), (2891.6, 3439.5, 4346.6, 5609.6, 7228.9)], index=GEN_power_vs_PF_index, columns=GEN_power_vs_PF_columns)
解决方案
Pandas本身没有直接的二维插值查询能力,需先将多级索引扁平化(转为数值型坐标轴),再借助SciPy的插值工具实现。
步骤1:扁平化索引,转换为数值型坐标轴
原多级索引的标签是元组,需提取其中的数值部分并转为float类型,方便插值计算:
# 重构行索引:提取PF数值并转为float GEN_power_vs_PF = GEN_power_vs_PF.rename(index=lambda idx: float(idx[1])) # 重构列索引:提取功率数值并转为float GEN_power_vs_PF.columns = GEN_power_vs_PF.columns.get_level_values(1).astype(float)
处理后DataFrame的行是PF数值(0.85/0.9/0.95/1.0),列是功率数值(201875/403750/...),数据为对应的值。
步骤2:使用SciPy实现二维插值
先安装SciPy(若未安装):
pip install scipy
方法一:RegularGridInterpolator(推荐,支持规则网格)
适合规则排列的网格数据,插值效率高:
from scipy.interpolate import RegularGridInterpolator # 提取插值所需的坐标轴和数据矩阵 pf_axis = GEN_power_vs_PF.index.values power_axis = GEN_power_vs_PF.columns.values data_matrix = GEN_power_vs_PF.values # 创建插值器 # bounds_error=False:目标值超出网格范围时不报错;fill_value=None:允许外插 interpolator = RegularGridInterpolator((pf_axis, power_axis), data_matrix, bounds_error=False, fill_value=None) # 查询目标点的插值结果 target_pf = 0.9769 target_power = 736381.3 interpolated_value = interpolator([[target_pf, target_power]])[0] print(f"插值结果:{interpolated_value:.2f}")
方法二:interp2d(支持自定义插值类型)
可选择线性、三次等插值方式:
from scipy.interpolate import interp2d # 创建插值函数,kind参数可选'linear'(默认)、'cubic'、'quintic' interp_func = interp2d(power_axis, pf_axis, data_matrix, kind='linear') # 查询目标值(注意参数顺序:先功率,后PF) interpolated_value = interp_func(target_power, target_pf)[0] print(f"插值结果:{interpolated_value:.2f}")
关键说明
df.loc仅支持标签匹配查询,无法处理插值,且原多级索引的标签是字符串(如'0.9'),直接用数值0.9查询会触发Key Error;- 上述方法基于规则网格插值,若数据为非规则网格,可使用
griddata函数实现插值。
内容的提问来源于stack exchange,提问作者ngom52
相关产品推荐
相关产品推荐

