Reputation: 20101
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
Reputation: 149
why not using argmin ?
df.iloc[np.argmin(df.loc[df['test_a'] == 'OK','metric_e'])]
Upvotes: 0
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
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
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
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