Pandas GroupBy и выберите строки с минимальным значением в определенном столбце

Я группирую свой набор данных по столбцу A, а затем хотел бы взять минимальное значение в столбце B и соответствующее значение в столбце C.

data = pd.DataFrame({'A': [1, 2], 'B':[ 2, 4], 'C':[10, 4]})
data  
    A   B   C
0   1   4   3
1   1   5   4
2   1   2   10
3   2   7   2
4   2   4   4
5   2   6   6  

и я хотел бы получить:

    A   B   C
0   1   2   10
1   2   4   4

На данный момент я группирую по A и создаю значение, которое указывает мне строки, которые я буду хранить в своем наборе данных:

a = data.groupby('A').min()
a['A'] = a.index
to_keep = [str(x[0]) + str(x[1]) for x in a[['A', 'B']].values]
data['id'] = data['A'].astype(str) + data['B'].astype('str')
data[data['id'].isin(to_keep)]

Я уверен, что есть гораздо более прямой способ сделать это. Я видел здесь много ответов, в которых используется мультииндексация, но я хотел бы сделать это, не добавляя мультииндекс в свой фрейм данных. Спасибо за помощь.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
25
0
18 798
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Я чувствую, что ты слишком много думаешь об этом. Просто используйте groupby и idxmin:

df.loc[df.groupby('A').B.idxmin()]

   A  B   C
2  1  2  10
4  2  4   4

df.loc[df.groupby('A').B.idxmin()].reset_index(drop=True)

   A  B   C
0  1  2  10
1  2  4   4

Спасибо! который работает с простой линией. Действительно, я не знал, что существует метод idxmin().

Wendy 01.02.2019 15:07

Я пробую это решение, но с pandas 1.0.0 я получаю сообщение об ошибке: Passing list-likes to .loc or [] with any missing labels is no longer supported . @ cs95 у вас есть предложения, как это исправить?

Eve Edomenko 18.08.2020 12:25

@ cs95 это приводит к одной строке на A, что, если есть несколько строк с минимальным значением для каждого из значений в A. что-то вроде всех студентов с минимальными оценками по естественным наукам.

A-dude 05.08.2021 13:22

Была аналогичная ситуация, но с более сложным заголовком столбца (например, "В знач"), и в этом случае это необходимо:

df.loc[df.groupby('A')['B val'].idxmin()]

Я нашел ответ немного более многословный, но намного эффективнее:

Это пример набора данных:

data = pd.DataFrame({'A': [1,1,1,2,2,2], 'B':[4,5,2,7,4,6], 'C':[3,4,10,2,4,6]})
data

Out:
   A  B   C
0  1  4   3
1  1  5   4
2  1  2  10
3  2  7   2
4  2  4   4
5  2  6   6 

Сначала мы получим минимальные значения в серии из операции groupby:

min_value = data.groupby('A').B.min()
min_value

Out:
A
1    2
2    4
Name: B, dtype: int64

Затем мы объединяем результат этой серии с исходным фреймом данных.

data = data.merge(min_value, on='A',suffixes=('', '_min'))
data

Out:
   A  B   C  B_min
0  1  4   3      2
1  1  5   4      2
2  1  2  10      2
3  2  7   2      4
4  2  4   4      4
5  2  6   6      4

Наконец, мы получаем только те строки, где B равно B_min, и отбрасываем B_min, так как он нам больше не нужен.

data = data[data.B==data.B_min].drop('B_min', axis=1)
data

Out:
   A  B   C
2  1  2  10
4  2  4   4

Я протестировал его на очень больших наборах данных, и это был единственный способ заставить его работать в разумные сроки.

Другие вопросы по теме