【问题标题】:Find closest column value in each row - pandas在每一行中查找最接近的列值 - 熊猫
【发布时间】:2020-09-04 23:25:21
【问题描述】:

这是一个更大数据集的样本:

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]})

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

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]})

【问题讨论】:

  • 你尝试了什么?
  • 尝试按照这个例子 (stackoverflow.com/questions/53969800/…) 但我认为附加的不相关列和某些行中的 NaN/错误字符串是问题...
  • 重要的是您告诉我们您尝试过做什么。一段代码通常很有用。 df=df_old.fillna(0) 然后df['nearest_forecast_windSpeed']=np.where(df.obs_windSpeed.sub(df.forecastWind_low)<df.obs_windSpeed.sub(df.forecastWind_high),df.forecastWind_low,df.forecastWind_high)

标签: python python-3.x pandas


【解决方案1】:

制作自定义比较函数并将其应用于各行

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
)

【讨论】:

  • 如果你的Nans实际上是字符串而不是np.nan,请检查这3个值是否是字符串而不是比较函数开头的np.nan
  • 谢谢。您的回复确实帮助我解决了这个问题。
【解决方案2】:

这是实现您所寻找的另一种方法。它允许比较多于两列。

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

【讨论】:

    【解决方案3】:

    修改杰夫的解决方案我设法想出了这个:

    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 并强制错误:

    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 建议的应用函数:

    df['nearest_forecastWindSpeed'] = df.apply(lambda x: check_speed_diff(
            x.forecast_WindSpeed_high, 
            x.forecast_WindSpeed_low,
            x.windSpeed),axis=1)
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-16
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多