Удалите повторяющиеся строки в DataFrame на основе одного столбца, содержащего подстроку

У меня есть фрейм данных, подобный следующему:

ID, Components
1,  "Room 1, ABC"
2,  "Room 2, ABC"
3,  "Room 3, DEF"
4,  "Room 1, DEF"
5,  "Room 3, DEF" 

Мне нужно отфильтровать фрейм данных так, чтобы в каждой комнате была только одна строка и сохранялось первое появление данной комнаты:

ID, Components
1,  "Room 1, ABC"
2,  "Room 2, ABC"
3,  "Room 3, DEF"

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

В качестве альтернативы также подойдет подсчет уникальных комнат, однако оставшаяся часть строки для Компонентов может повторяться, например. ABC и DEF может быть множество, но только 1 Комната 1/2/3...

Поэтому подсчет уникальных записей в столбце «Компоненты» не будет работать. Он должен быть уникальным только для «Комнаты n».

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

Ответы 5

IIUC, извлеките идентификатор комнаты и используйте дублированный , чтобы сформировать маску для логического индексирования:

df = pd.DataFrame({'ID': [1,2,3,4,5],
                   'Components': ['Room 1, ABC',
                                  'Room 2, ABC',
                                  'Room 3, DEF',
                                  'Room 1, DEF',
                                  'Room 3, DEF']})

m = df['Components'].str.extract(r'(Room \d+)', expand=False).duplicated()

out = df[~m]

Выход:

   ID   Components
0   1  Room 1, ABC
1   2  Room 2, ABC
2   3  Room 3, DEF

Промежуточные продукты:

   ID   Components extract      m     ~m
0   1  Room 1, ABC  Room 1  False   True
1   2  Room 2, ABC  Room 2  False   True
2   3  Room 3, DEF  Room 3  False   True
3   4  Room 1, DEF  Room 1   True  False
4   5  Room 3, DEF  Room 3   True  False
Ответ принят как подходящий

Входные данные:

df = pd.DataFrame({'ID': np.arange(1, 6), 'Components': ['Room 1, ABC', 'Room 2, ABC', 'Room 3, DEF', 'Room 1, DEF', 'Room 3, DEF']})

Используйте str.extract:

df.loc[~df['Components'].str.extract('(\d+)').duplicated()]

Выход:

   ID   Components
0   1  Room 1, ABC
1   2  Room 2, ABC
2   3  Room 3, DEF

Отлично, это сработало, как и ожидалось. Спасибо!

Andy Paling 20.06.2024 12:20

@AndyPaling Рад помочь :)

U13-Forward 20.06.2024 12:21

Я бы проголосовал за, но у меня пока недостаточно репутации!

Andy Paling 20.06.2024 12:21

@AndyPaling Не беспокойся! Не стесняйтесь голосовать за него, как только наберете достаточно репутации!

U13-Forward 20.06.2024 12:23

Сойдет, всего в нескольких баллах, хаха..

Andy Paling 20.06.2024 12:29

Использование groupby.first

df.groupby(df["Components"].str.extract(r"^(Room\s+\d+)", 
              expand=False), as_index=False).first()

Я считаю, что добавлять groupby сюда не нужно, так как это отнимает дополнительное время на обработку.

U13-Forward 19.06.2024 14:11

Сначала создайте фрейм данных для ваших данных:

df = pd.DataFrame(data)

### Extract the room number from the 'Components' column
df['Room'] = df['Components'].apply(lambda x: x.split(',')[0].strip())

### Drop duplicates based on the 'Room' column, keeping the first occurrence
df_filtered = df.drop_duplicates(subset='Room', keep='first')

### Drop the 'Room' column as it's no longer needed
df_filtered = df_filtered.drop(columns=['Room'])

Это предоставит вам отфильтрованный список с номером комнаты в качестве уникального ключа.

Добавьте новый столбец для «комнат», используя регулярное выражение, чтобы извлечь их из «Компонентов»:

df["extract"] = df["Components"].str.extract("(.+,)")

Затем сгруппируйте одинаковые «комнаты» и для каждой группы выберите первый пункт:

df.groupby("extract").first()

Если вы хотите удалить «извлеченный» индекс:

df.groupby("extract").first().reset_index(drop=True)

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