Python 填充来自邻居值的值,该值与表中的其他列相匹配

Python 填充来自邻居值的值,该值与表中的其他列相匹配,python,pandas,dataframe,Python,Pandas,Dataframe,我有这样的数据帧: 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

我有这样的数据帧:

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以外的值)

然后,使用这个数组,我实现了
replaceAdvisority
函数,它获取数据帧中的每一行,首先检查值是否已经存在。如果是,它将直接替换它。否则,它将用分组数据帧中最近的
方位
值替换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

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

首先将所有ID设置为nan(如果为100)

df.id = np.where(df.id==100, np.nan, df.id)
然后两两计算角度差,找到最接近的ID来填充NAN

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

如果您已经有了id列(这似乎是最难的部分),您能否
df['id']%100+1
@Kenan不确定我是否理解?
例外情况除外:打印(a)
是一种不好的做法,至少有两个原因,请小心。