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
)。01:00:00
选择18
)。输出应为:
A B C
3 01:00:00 18 Fred
7 02:00:00 14 Fred
答案 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)
min
和key
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')