Как извлечь элемент списка групп, используя критерии pandas

У меня есть фрейм данных pandas, как показано ниже.

ID,color
1, Yellow
1, Red
1, Green
2, Red
2, np.nan
3, Green
3, Red
3, Green
4, Yellow
4, Red
5, Green
5, np.nan
6, Red
7, Red

fd = pd.read_clipboard(sep=',')

Как вы можете видеть во входном фрейме данных, некоторые идентификаторы имеют несколько связанных с ними цветов.

Итак, всякий раз, когда с ними связано несколько цветов, я хотел бы выбрать только один цвет на основе приведенных ниже критериев.

['Green','Red','Yellow'] = Choose 'Green'
['Red', 'Yellow'] = Choose 'Yellow'
['Green', 'Yellow'] = Choose 'Green'

В основном, Зеленому отдается 1-е предпочтение. 2-е предпочтение принадлежит желтому цвету, а последнее предпочтение — красному цвету.

Таким образом, если идентификатор всегда имеет зеленый цвет, выберите зеленый (не заботьтесь о других цветах).

Если идентификатор всегда имеет желтый и красный цвет, выберите желтый.

Если идентификатор для всех его строк имеет только NA, оставьте его как NA

Я пробовал ниже, но это дает мне только список цветов

fd.groupby('ID',as_index=False)['color'].aggregate(lambda x: list(x))
fd[final_color] = [if i[0] =='Green' for i in fd[col]]

Я ожидаю, что мой вывод будет таким, как показано ниже

Как извлечь элемент списка групп, используя критерии pandas

Обновить

Как извлечь элемент списка групп, используя критерии pandas

Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
28
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Один из способов решить эту проблему — реализовать пользовательскую сортировку:

sort_preference = {
    'Green': 0,
    'Yellow': 1,
}

(
    fd
    .sort_values(by=['color'], key=lambda x: x.map(sort_preference))
    .groupby('ID')
    .head(1)
)

спасибо, проголосовал. есть ли способ сделать это без сортировки?

The Great 20.03.2022 07:51

Ответ @Shubham Sharma имеет версию без сортировки. Это достигается путем присвоения упорядоченных категорий.

SultanOrazbayev 20.03.2022 07:54
Ответ принят как подходящий

Отсортируйте значения фрейма данных по цвету с помощью словаря предпочтений, затем отбросьте дубликаты на ID

d = {'Green': 1, 'Yellow': 2, 'Red': 3}
df.sort_values('color', key=lambda c: c.map(d)).drop_duplicates('ID')

Альтернативный подход: сначала преобразовать столбец color в упорядоченный категориальный тип, затем сгруппировать и агрегировать, чтобы выбрать минимальное значение.

df['color'] = pd.Categorical(df['color'], ['Green', 'Yellow', 'Red'], True)
df.groupby('ID', as_index=False)['color'].agg('min')

   ID   color
0   1   Green
1   2     Red
2   3   Green
3   4  Yellow
4   5   Green
5   6     Red
6   7     Red

спасибо, проголосовал. Есть ли способ сделать это без сортировки? Или эта проблема всегда будет требовать сортировки? из-за своей природы? Скажем, если я хочу выбрать определенный цвет из списка (без каких-либо критериев), может просто показать мне, как это можно сделать? Вы также можете сохранить этот пример сортировки как есть.

The Great 20.03.2022 07:54

Предположим, я хочу выбрать «зеленый» цвет на основе ID=1,3 и желтый цвет для ID=6,7. Можете показать мне, как это можно сделать?

The Great 20.03.2022 07:55

@TheGreat В таком случае, какой будет выбор цвета для id 2, 4, 5?

Shubham Sharma 20.03.2022 07:59

Это немного другое требование (не связанное с этим вопросом). Я создам новый пост и свяжу его здесь

The Great 20.03.2022 08:03

Вот соответствующий пост - stackoverflow.com/questions/71544776/…

The Great 20.03.2022 08:11

случайно, вы не знаете, почему я получаю все NA, когда делаю категорический заказ? обновил скрин выше в посте

The Great 20.03.2022 08:38

@TheGreat Это связано с дополнительными пробелами в столбце цвета во входном фрейме данных. Используйте fd = pd.read_clipboard(sep=',', skipinitialspace=True) во время чтения.

Shubham Sharma 20.03.2022 08:40

Без сортировки вы можете использовать idxmin, если вы сопоставляете свой цвет с числовыми значениями:

d = {'Green': 1, 'Yellow': 2, 'Red': 3}
out = df.loc[df.assign(num=df['color'].map(d)).groupby('ID')['num'].idxmin()]
print(out)

# Output
    ID   color
2    1   Green
3    2     Red
5    3   Green
8    4  Yellow
10   5   Green
12   6     Red
13   7     Red

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