У меня есть фрейм данных, подобный следующему:
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».






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
@AndyPaling Рад помочь :)
Я бы проголосовал за, но у меня пока недостаточно репутации!
@AndyPaling Не беспокойся! Не стесняйтесь голосовать за него, как только наберете достаточно репутации!
Сойдет, всего в нескольких баллах, хаха..
Использование groupby.first
df.groupby(df["Components"].str.extract(r"^(Room\s+\d+)",
expand=False), as_index=False).first()
Я считаю, что добавлять groupby сюда не нужно, так как это отнимает дополнительное время на обработку.
Сначала создайте фрейм данных для ваших данных:
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)
Отлично, это сработало, как и ожидалось. Спасибо!