Ivan
Ivan

Reputation: 20101

Filter a Pandas dataframe by a condition and a minimum value in a column

I have a dataframe similar to

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

and I want to filter by one condition, meaning that test_a == OK and capture the minimum value on metric_e. I can accomplish that with two lines, copying a dataframe:

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

Is there a way to do it without having to use an intermediate dataframe?

Upvotes: 4

Views: 15354

Answers (5)

AlexVI
AlexVI

Reputation: 149

why not using argmin ?

df.iloc[np.argmin(df.loc[df['test_a'] == 'OK','metric_e'])]

Upvotes: 0

BENY
BENY

Reputation: 323226

Slice after 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

Upvotes: 0

jezrael
jezrael

Reputation: 862511

In my opinion your solution is nice, also is possible join both rows of code together with double [] for return one row 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

Upvotes: 4

perl
perl

Reputation: 9941

Using nsmallest:

df[df['test_a']=='OK'].nsmallest(1, 'metric_e')

Output:

  test_a test_b  metric_e
2     OK    NOK         2

Upvotes: 8

anky
anky

Reputation: 75080

With the output from your code, you can try with:

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

If don't want transpose:

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

  test_a test_b  metric_e
2     OK    NOK         2

Upvotes: 1

Related Questions