繁体   English   中英

将值替换为Pandas数据帧中最近邻居的值

[英]Replace value with the value of nearest neighbor in Pandas dataframe

我在获取pandas数据帧中某些行的最接近值时遇到问题,并使用这些行中的值填充另一列。

数据样本我有:

id   su_id  r_value  match_v

A      A1      0        1
A      A2      0        1
A      A3      70       2
A      A4      120      100
A      A5      250      3
A      A6      250      100
B      B1      0        1
B      B2      30       2

问题是,无论match_v等于100 ,我需要更换100与其中行的值r_value最接近r_value从原点行(其中match_v等于100 ),但只是withing组(由ID分组)

预期产出

id   su_id  r_value  match_v

A      A1      0        1
A      A2      0        1
A      A3      70       2
A      A4      120      2
A      A5      250      3
A      A6      250      3
B      B1      0        1
B      B2      30       2

我尝试过制造带有移位的铅和腿,然后发现差异。 但是效果并不好,它在某种程度上搞砸了已经很好的价值观。 我没有尝试任何其他因为我真的没有任何想法。

欢迎任何帮助或提示,如果您需要任何其他信息,我在这里。

提前致谢。

更像merge_asof

s=df.loc[df.match_v!=100]
s=pd.merge_asof(df.sort_values('r_value'),s.sort_values('r_value'),on='r_value',by='id',direction='nearest')
df['match_v']=df['su_id'].map(s.set_index('su_id_x')['match_v_y'])
df
Out[231]: 
  id su_id  r_value  match_v
0  A    A1        0        1
1  A    A2        0        1
2  A    A3       70        2
3  A    A4      120        2
4  A    A5      250        3
5  A    A6      250        3
6  B    B1        0        1
7  B    B2       30        2

这是使用numpy广播的另一种方式,用于加速计算

l=[]
for x , y in df.groupby('id'): 
    s1=y.r_value.values
    s=abs((s1-s1[:,None])).astype(float)
    s[np.tril_indices(s.shape[0], 0)] = 999999
    s=s.argmin(0)
    s2=y.match_v.values
    l.append(s2[s][s2==100])
df.loc[df.match_v==100,'match_v']=np.concatenate(l)
df
Out[264]: 
  id su_id  r_value  match_v
0  A    A1        0        1
1  A    A2        0        1
2  A    A3       70        2
3  A    A4      120        2
4  A    A5      250        3
5  A    A6      250        3
6  B    B1        0        1
7  B    B2       30        2

您可以定义一个自定义函数来执行计算和替换,然后将其与groupby一起使用并应用。

def mysubstitution(x):
    for i in x.index[x['match_v'] == 100]:
        diff = (x['r_value'] - (x['r_value'].iloc[i])).abs()
        exclude = x.index.isin([i])
        closer_idx = diff[~exclude].idxmin()
        x['match_v'].iloc[i] = x['match_v'].iloc[closer_idx]
    return x

ddf = df.groupby('id').apply(mysubstitution)

ddf是:

  id su_id  r_value  match_v
0  A    A1        0        1
1  A    A2        0        1
2  A    A3       70        2
3  A    A4      120        2
4  A    A5      250        3
5  A    A6      250        3
6  B    B1        0        1
7  B    B2       30        2

假设在第一次遇到100时,组内总是至少有一个有效值。

m = dict()
for i in range(len(df)):
    if df.loc[i, "match_v"] == 100:
        df.loc[i, "match_v"] = m[df.loc[i, "id"]]
    else:
        m[df.loc[i, "id"]] = df.loc[i, "match_v"]

暂无
暂无

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

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