如何在Pandas中基于两列最近值匹配返回对应行?
在Pandas中查找同时匹配两列最接近指定值的单行方法
需求:找到DataFrame中同时满足Site和DTP两列数值最接近指定值的单行,而非分别匹配两列的不同行。例如:
- 查找
Site=0.79、DTP=59时,应返回示例数据中的行23 - 查找
Site=0.79、DTP=39时,应返回示例数据中的行11
示例数据
Site DTP Capacity WTG AVAIL OpEx 11 0.8 40 2000 18.0 0.966 46268 23 0.8 60 2000 18.0 0.964 46939 35 0.8 100 2000 18.0 0.964 50904 11 0.8 40 2000 18.0 0.966 46268 11 0.8 40 2000 18.0 0.966 46268 11 0.8 40 2000 18.0 0.966 46268 59 0.8 200 2000 18.0 0.979 60734 71 1.2 40 2000 18.0 0.965 49000 107 1.2 150 2000 18.0 0.975 60279 107 1.2 150 2000 18.0 0.975 60279 83 1.2 60 2000 18.0 0.963 49580 23 0.8 60 2000 18.0 0.964 46939 155 1.6 100 2000 18.0 0.965 59660 47 0.8 150 2000 18.0 0.979 60290 35 0.8 100 2000 18.0 0.964 50904 167 1.6 150 2000 18.0 0.965 59993 11 0.8 40 2000 18.0 0.966 46268 203 2.0 60 2000 18.0 0.951 58726 35 0.8 100 2000 18.0 0.964 50904 239 2.0 200 2000 18.0 0.951 59836 59 0.8 200 2000 18.0 0.979 60734 23 0.8 60 2000 18.0 0.964 46939 227 2.0 150 2000 18.0 0.951 59392 59 0.8 200 2000 18.0 0.979 60734 299 2.4 200 2000 18.0 0.923 58739
无效代码示例
用户尝试的代码无法实现需求:
df_closest = subdf.iloc[(subdf['Site']-.79).abs().argsort()[:1] & (subdf['DTP']-59).abs().argsort()[:1]]
原因:argsort()[:1]返回单个索引的数组,&在这里做元素级布尔运算,无法找到同时满足两列最接近条件的行。
可行解决方案
方法1:计算绝对误差之和(推荐,直观易调整)
通过累加两列的绝对误差,找到总误差最小的行,可根据需求给不同列的误差添加权重:
# 定义目标值 target_site = 0.79 target_dtp = 59 # 计算每行的总误差(可根据需求添加权重,例如0.7*Site误差 + 0.3*DTP误差) subdf['total_error'] = (subdf['Site'] - target_site).abs() + (subdf['DTP'] - target_dtp).abs() # 按总误差升序排序,取第一行 closest_row = subdf.sort_values('total_error').iloc[0] # 可选:删除临时计算的total_error列 closest_row = closest_row.drop('total_error')
方法2:计算欧氏距离(适合多列匹配场景)
用欧氏距离衡量行与目标值的整体接近程度,适合需要匹配3列及以上的场景:
import numpy as np # 定义目标列和目标值 target_cols = ['Site', 'DTP'] target_values = np.array([target_site, target_dtp]) # 计算每行与目标值的欧氏距离 subdf['euclidean_distance'] = np.linalg.norm(subdf[target_cols] - target_values, axis=1) # 按距离升序排序,取第一行 closest_row = subdf.sort_values('euclidean_distance').iloc[0].drop('euclidean_distance')
说明
两种方法本质都是通过综合评估两列的接近程度来找到最优行,避免了分别取两列最接近行的问题。如果存在多行总误差/距离相同,iloc[0]会返回排序后的第一行,可根据需求调整为返回所有符合条件的行(如subdf[subdf['total_error'] == subdf['total_error'].min()])。
内容的提问来源于stack exchange,提问作者Matthew Barlow
相关产品推荐
相关产品推荐

