#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