繁体   English   中英

填充来自 Pandas 中其他列的邻居值的值

[英]Fill with the values from neighbor value compering other column in Pandas

我有这样的数据框:

azimuth   id
15        100
15        1     
15        100
150       2
150       100
240       3
240       100
240       100
350       100

我需要的是从方位角最接近的行填充 100 个值:所需的输出:

azimuth      id
    15        1
    15        1     
    15        1
    150       2
    150       2
    240       3
    240       3
    240       3
    350       1

350 接近 15,因为这是一个圆(角度表示)。 相差25。

我拥有的:

def mysubstitution(x):
    for i in x.index[x['id'] == 100]:
        i = int(i)
        diff = (x['azimuth'] - x.loc[i, 'azimuth']).abs()
        for ind in diff.index:
            if diff[ind] > 180:
                diff[ind] = 360 - diff[ind]
            else:
                pass
        exclude = [y for y in x.index if y not in x.index[x['id'] == 100]]
        closer_idx = diff[exclude]
        closer_df = pd.DataFrame(closer_idx)
        sorted_df = closer_df.sort_values('azimuth', ascending=True)
        try:
            a = sorted_df.index[0]
            x.loc[i, 'id'] = x.loc[a, 'id']
        except Exception as a:
            print(a)
    return x

大多数情况下都可以正常工作,但我想有一些更简单的解决方案。

提前致谢。

我尝试分两步实现该功能。 首先,对于每个方位角,我将另一个保存其 id 值的数据框分组(对于 100 以外的值)。

然后,使用这个数组,我实现了replaceAzimuth函数,它获取数据帧中的每一行,首先检查该值是否已经存在。 如果是这样,它直接替换它。 否则,它将用分组数据帧中最接近的azimuth值替换 id 值。

这是实现:

df = pd.DataFrame([[15,100],[15,1],[15,100],[150,2],[150,100],[240,3],[240,100],[240,100],[350,100]],columns=['azimuth','id'])

df_non100 = df[df['id'] != 100]
df_grouped = df_non100.groupby(['azimuth'])['id'].min().reset_index()

def replaceAzimuth(df_grouped,id_val):
    real_id = df_grouped[df_grouped['azimuth'] == id_val['azimuth']]['id']
    if real_id.size == 0:
        df_diff = df_grouped
        df_diff['azimuth'] = df_diff['azimuth'].apply(lambda x: min(abs(id_val['azimuth'] - x),(360 - id_val['azimuth'] + x)))
        id_val['id'] = df_grouped.iloc[df_diff['azimuth'].idxmin()]['id']
    else:
        id_val['id'] = real_id
    return id_val


df = df.apply(lambda x: replaceAzimuth(df_grouped,x), axis = 1)

df

对我来说,代码似乎给出了您显示的输出。 但不确定是否适用于所有情况!

如果它们是 100,首先将所有 id 设置为 nan。

df.id = np.where(df.id==100, np.nan, df.id)

然后成对计算角度差异并找到最接近的 ID 来填充 nans。

df.id = df.id.combine_first(
    pd.DataFrame(np.abs(((df.azimuth.values[:,None]-df.azimuth.values) +180) % 360 - 180))
    .pipe(np.argsort)
    .applymap(lambda x: df.id.iloc[x])
    .apply(lambda x: x.dropna().iloc[0], axis=1)
)

df
    azimuth id
0   15      1.0
1   15      1.0
2   15      1.0
3   150     2.0
4   150     2.0
5   240     3.0
6   240     3.0
7   240     3.0
8   350     1.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM