在使用下面生成的数据集 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()
,但这是完全错误的!
答案 0 :(得分:1)
使用argsort
,过滤索引的前3个值并传递给iloc
,另外,group_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