Фильтровать фрейм данных Pandas по условию и минимальному значению в столбце

#python #pandas

#python #pandas

Вопрос:

У меня есть фрейм данных, подобный

   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
  

Есть ли способ сделать это без использования промежуточного фрейма данных?

Комментарии:

1. Вы уверены, что ваш вывод соответствует предоставленному вами коду?

2. Если вы хотите захватить индекс, df2[(df2.test_a == ‘OK’) amp; (df2.metric_e == df2.metric_e.min())]

3. Мне нужно получить все значения в строке фрейма данных, которые соответствуют условию в test_a и являются минимальным значением в metric_e для этого подмножества

4. @Vaishali — нет, потому что нужен фильтр в уже отфильтрованных данных, поэтому здесь не может быть использован

5. Это похоже, но, вероятно, не обман, поскольку строка, которую вы упоминаете, вызовет ошибку, если минимальное значение будет отфильтровано по условию 1.

Ответ №1:

Используя nsmallest :

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

Вывод:

   test_a test_b  metric_e
2     OK    NOK         2
  

Комментарии:

1. Самый краткий ответ imo 1

2. Если ваш вопрос о том, как его использовать, вам не обязательно сортировать значения для использования nsmallest . И если вы спрашиваете о том, как это реализовано в pandas, я только что просмотрел это, и это выглядит очень интересно, они, по-видимому, сортируют не все значения, а используют какой-то алгоритм выбора. В их комментарии говорится This method is equivalent to df.sort_values(columns, ascending=True).head(n), but more performant. (см. github.com/pandas-dev/pandas/blob/master/pandas/core/frame.py , выполните поиск nsmallest )

Ответ №2:

На мой взгляд, ваше решение хорошее, также возможно объединить обе строки кода вместе с double [] для возврата одной строки 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
  

Ответ №3:

Используя выходные данные вашего кода, вы можете попробовать с:

 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
  

Ответ №4:

Фрагмент после 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