选择数据框中具有最接近值的行

时间:2018-03-29 22:00:26

标签: python pandas conditional

          A   B       C
0  01:00:00  24  Andrew
1  01:00:00  28     Edd
2  01:00:00  12    Emma
3  01:00:00  18    Fred
4  02:00:00  17  Andrew
5  02:00:00  35     Edd
6  02:00:00  45    Emma
7  02:00:00  14    Fred

我想为每个A组选择一行,具有以下条件:

  • 选择最接近的B值为15(如果是02:00:00,则最接近15的值为14)。
  • 如果有两个最接近15的值,请选择其中较大的值(如果01:00:00选择18)。

输出应为:

          A   B       C
3  01:00:00  18    Fred
7  02:00:00  14    Fred

4 个答案:

答案 0 :(得分:2)

groupby这里是特殊情况如果有两个最接近15的值,请选择其中较大的

df.sort_values('B',ascending=False).assign(New=(df.B-15).abs()).groupby(['A','New']).head(1).drop_duplicates('A',keep='last')
Out[486]: 
          A   B     C  New
3  01:00:00  18  Fred    3
7  02:00:00  14  Fred    1

答案 1 :(得分:2)

minkey

相关的乐趣
key = lambda x: (abs(x[1] - 15), -x[1])
f = lambda d: min(d.items(), key=key)[0]
df.loc[df.B.groupby(df.A).apply(f)]

          A   B     C
3  01:00:00  18  Fred
7  02:00:00  14  Fred

np.lexsort

怎么样?
df.iloc[np.lexsort(
    [-df.B, df.B.sub(15).abs()]
)].groupby('A').head(1)

          A   B     C
3  01:00:00  18  Fred
7  02:00:00  14  Fred

答案 2 :(得分:0)

另一种解决方案是创建辅助列,对值进行排序并删除重复项:

df['D'] = list(zip((df['B'] - 15).abs(), df['B'] - 15 < 0))

res = df.sort_values('D').drop_duplicates('A').drop('D', 1)

          A   B       C
4  02:00:00  17  Andrew
3  01:00:00  18    Fred

我们的想法是,您可以按升序连续按每个元素对元组列D进行排序,因为这是元组在Python中的排序方式。

答案 3 :(得分:0)

我们可以使用15.1的abs来确保16比14更接近等等。

重新索引和dropduplicates:

df = df.reindex((df['B']-15.1).abs().sort_values().index).drop_duplicates('A')
print(df)

          A   B     C
7  02:00:00  14  Fred
3  01:00:00  18  Fred

或者使用iloc和2行(还添加了一个排序函数以获得最短的时间)

newIndex = (df['B']-15.1).abs().sort_values().index
df = df.iloc[newIndex].drop_duplicates('A').sort_values(by='A')