按条件和列最小值过滤Pandas数据框

4

我有一个类似于Dataframe的数据结构

  test_a test_b  metric_e
0     OK    NOK        12
1     OK     OK         7
2     OK    NOK         2
3     OK     OK        55

我希望通过一个条件进行筛选,即 test_a == OK 并捕获 metric_e 的最小值。我可以通过复制数据框来实现这一目标,只需两行代码:

df_t = df[df.test_a == 'OK'].reset_index(drop=True)
df_t.iloc[df_t.metric_e.idxmin()].to_frame()

test_a | test_b | metric_e
OK     |  NOK   | 2

有没有一种方法可以不使用中间数据框来完成这个操作?


你确定你提供的代码输出是正确的吗? - user3483203
如果你想要捕获索引,可以使用以下代码:df2[(df2.test_a == 'OK') & (df2.metric_e == df2.metric_e.min())] - Vaishali
我需要获取数据框中符合test_a条件且在该子集上metric_e值最小的行中的所有值。 - Ivan
1
@Vaishali - 不行,因为需要在已经过滤的数据中进行筛选,所以不能在这里使用。 - jezrael
这两者很相似,但可能不是完全重复的,因为如果条件1过滤掉了最小值,那么你提到的那一行代码会导致错误。 - Ivan
现在还不用担心。我认为在这种情况下,我更关心的是内存使用而不是运行时间,但是我的数据集现在相当小。 - Ivan
4个回答

8
使用 nsmallest 方法:
df[df['test_a']=='OK'].nsmallest(1, 'metric_e')

输出:

  test_a test_b  metric_e
2     OK    NOK         2

2
我认为这是最简洁的答案 +1 - Erfan
1
如果你的问题是关于如何使用nsmallest,那么你不必对值进行排序。如果你问的是它在pandas中的实现方式,我刚刚查了一下,看起来非常有趣,他们显然没有对所有的值进行排序,而是使用了某种选择算法。他们的注释说这个方法等同于df.sort_values(columns, ascending=True).head(n),但更高效。(参见https://github.com/pandas-dev/pandas/blob/master/pandas/core/frame.py,搜索`nsmallest`) - perl

4

在我看来,您的解决方案很不错。同时,可以使用双[]将两行代码合并为一个DataFrame

df = df.loc[[df.loc[df.test_a == 'OK', 'metric_e'].idxmin()]]
print (df)
  test_a test_b  metric_e
2     OK    NOK         2

1
使用您的代码输出,您可以尝试使用以下内容:
df[df.metric_e==df.loc[df.test_a.eq('OK'),'metric_e'].min()].T

            2
test_a     OK
test_b    NOK
metric_e    2

如果不想转置:

df[df.metric_e==df.loc[df.test_a.eq('OK'),'metric_e'].min()]

  test_a test_b  metric_e
2     OK    NOK         2

0

sort_values 之后进行切片

df.query("test_a=='OK'").sort_values('metric_e').iloc[[0]]# or head(1)
Out[658]: 
  test_a test_b  metric_e
2     OK    NOK         2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接