首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在每行中查找最接近的列值- pandas

在每行中查找最接近的列值- pandas
EN

Stack Overflow用户
提问于 2020-09-04 08:38:55
回答 3查看 115关注 0票数 1

以下是一个更大的数据集的示例:

代码语言:javascript
复制
df_old = pd.DataFrame({'code': ['fea-1','fea-132','fea-223','fea-394','fea-595','fea-130','fea-495'],
                   'forecastWind_low':[20,15,0,45,45,25,45],
                   'forecastWind_high':['NaN' ,30,'NaN',55,65,35,'NaN'],
                   'obs_windSpeed':[20,11,3,65,55,'NaN',55]})

我预测了风速,我需要与观测值进行比较。最终,我需要找到与观测风速值最接近的预测风速(低或高),以获得如下输出:

代码语言:javascript
复制
df_new = pd.DataFrame({'code': ['fea-1','fea-132','fea-223','fea-394','fea-595','fea-130','fea-495'],
                   'forecastWind_low':[20,15,0,45,45,25,45],
                   'forecastWind_high':['NaN' ,30,'NaN',55,65,35,'NaN'],
                   'obs_windSpeed':[20,11,3,65,55,'NaN',55],
                   'nearest_forecast_windSpeed':[20,15,0,55,45,'NaN',45]})
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-09-04 09:22:40

创建自定义比较函数并将其应用于各行

代码语言:javascript
复制
def check_speed_diff(high,low,obs):
    if np.isnan(obs):
        return np.nan
    elif np.isnan(high):
        return low
    elif np.isnan(low):
        return high
    
    if abs(high-obs)<abs(low-obs):
        return high
    else:
        return low

df_old.apply(lambda x: 
    check_speed_diff(
        x.forecastWind_high,
        x.forecastWind_low,
        x.obs_windSpeed
    ),
    axis=1
)
票数 1
EN

Stack Overflow用户

发布于 2020-09-04 21:07:41

这是另一种实现你想要的东西的方法。它允许不止两列进行比较。

代码语言:javascript
复制
col = ['forecastWind_low','forecastWind_high']
comparecol = ['obs_windSpeed']
df[col + comparecol] = df[col + comparecol].astype(float)
dfmerge =pd.merge(df[col].stack().reset_index(-1),df[comparecol],left_index=True,right_index=True,how='left')
dfmerge = dfmerge.rename(columns = {'level_1':'windforecast',0:'Amount'})
dfmerge['difference'] = abs(dfmerge['obs_windSpeed'] - dfmerge['Amount'])
dfmerge = dfmerge.sort_values(by='difference',ascending=True)
dfmerge = dfmerge.groupby(level=0).head(1)
df = pd.merge(df,dfmerge['Amount'],left_index=True,right_index=True,how='left')
df.loc[df['obs_windSpeed'].isna(),'Amount'] = np.nan
票数 1
EN

Stack Overflow用户

发布于 2020-09-04 23:25:22

在修改Jeff的解决方案时,我设法想出了这个:

代码语言:javascript
复制
def check_speed_diff(high,low,obs):
    if obs == 'NaN':
        return np.nan
    if low != 'NaN' and high == 'NaN':
        return low
    if low == 'NaN' and high != 'NaN':
        return high
    if low != 'NaN' and high != 'NaN':
        if abs(high-obs)<abs(low-obs):
            return high
        else:
            return low

我遇到的另一个问题是一些列/行中的字符串不是'NaN',所以我使用pandas并强制执行错误:

代码语言:javascript
复制
df.forecast_WindSpeed_high = pd.to_numeric(df.forecast_WindSpeed_high,errors='coerce')
df.forecast_WindSpeed_low = pd.to_numeric(df.forecast_WindSpeed_low ,errors='coerce')

使用Jeff建议的应用函数:

代码语言:javascript
复制
df['nearest_forecastWindSpeed'] = df.apply(lambda x: check_speed_diff(
        x.forecast_WindSpeed_high, 
        x.forecast_WindSpeed_low,
        x.windSpeed),axis=1)

可能不是最有效率的,但我完成了工作...感谢大家的帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63733381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档