首页 > 解决方案 > 最接近标记的 3 个值

问题描述

在使用以下生成的数据集df1 ...

import pandas as pd
import numpy as np

n = 3  # no of closest values

i = ['dog', 'cat', 'rabbit', 'elephant'] * 20

df = pd.DataFrame(np.random.randn(len(i), 2), index=i, columns=list('AB'))
df_m = pd.DataFrame({'animal':i[:4], 'marker': [0.5, 0.3, 0.2, 1.8]})
df1 = df.join(df_m.set_index('animal')).rename_axis('animal').reset_index()

...代码df1.iloc[df1.groupby('animal').apply(lambda g: abs(g.A - g.marker).idxmin())]给出了最接近标记的“A”值。

如何获得与标记最接近的 3 个值的数据框?尝试做argsort()而不是idxmin(),但这是完全错误的!

标签: pandas

解决方案


使用argsort,过滤 index 的前 3 个值并传递给ilocgroup_keys=False参数也用于避免MultiIndex

np.random.seed(2019)

i = ['dog', 'cat', 'rabbit', 'elephant'] * 20
n = 3  # no of closest values

df = pd.DataFrame(np.random.randn(len(i), 2), index=i, columns=list('AB'))
df_m = pd.DataFrame({'animal':i[:4], 'marker': [0.5, 0.3, 0.2, 1.8]})

df1 = df.join(df_m.set_index('animal')).rename_axis('animal').reset_index()
#print (df1)

#for compare first values
print (df1.iloc[df1.groupby('animal').apply(lambda g: abs(g.A - g.marker).idxmin())])
      animal         A         B  marker
17       cat  0.306880 -1.206507     0.3
30       dog  0.593167  1.471711     0.5
48  elephant  1.654258  0.656859     1.8
71    rabbit  0.211549 -0.275927     0.2

df2 = (df1.groupby('animal', group_keys=False)
          .apply(lambda g: g.iloc[np.abs(g.A - g.marker).argsort()[:3]]))
print (df2)
      animal         A         B  marker
17       cat  0.306880 -1.206507     0.3
12       cat  0.289708 -1.352658     0.3
3        cat  0.410928  0.486689     0.3
30       dog  0.593167  1.471711     0.5
39       dog  0.806910 -1.374152     0.5
23       dog  0.807277  0.474141     0.5
48  elephant  1.654258  0.656859     1.8
45  elephant  1.488947 -0.792520     1.8
50  elephant  1.082502 -0.688914     1.8
71    rabbit  0.211549 -0.275927     0.2
69    rabbit  0.235083  0.115154     0.2
70    rabbit  0.263348 -0.516921     0.2

推荐阅读