#python #pandas #duplicates
#python #pandas #дубликаты #удаление дубликатов
Вопрос:
pandas
drop_duplicates
Функция отлично подходит для «унификации» фрейма данных. Однако одним из ключевых аргументов для передачи является take_last=True
или take_last=False
, в то время как я хотел бы удалить все строки, которые являются дубликатами в подмножестве столбцов. Возможно ли это?
A B C
0 foo 0 A
1 foo 1 A
2 foo 1 B
3 bar 1 A
В качестве примера я хотел бы удалить строки, которые совпадают по столбцам A
, и C
поэтому при этом должны быть удалены строки 0 и 1.
Ответ №1:
Теперь в pandas это намного проще с помощью drop_duplicates и параметра keep.
import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.drop_duplicates(subset=['A', 'C'], keep=False)
Комментарии:
1. Что делать, если мои столбцы явно не помечены? Как мне выбрать столбцы только на основе их индекса?
2. Может
df.reindex(df.iloc[:,[0,2]].drop_duplicates(keep=False).index)
быть?3. вы можете попробовать
df.drop_duplicates(subset=[df.columns[0:2]], keep = False)
4. Если у вас
subset
есть только один столбецA
,keep=False
то он удалит все строки. Если вы определяетеkeep
какfirst
илиlast
, вы сохраните хотя бы одну запись из всех. Это не относится к вопросу, но если ваше подмножество представляет собой один столбец (как в моем случае), эта информация может быть полезна при работе сdrop_duplicates
методом: вы можете потерять много записей, вместо того, чтобы просто удалять дубликаты. С уважением :).
Ответ №2:
Просто хочу добавить к ответу Бена на drop_duplicates:
keep
: {‘first’, ‘last’, False}, по умолчанию ‘first’
- первое: удалите дубликаты, за исключением первого вхождения.
- последнее: удалите дубликаты, за исключением последнего вхождения.
- False: удалите все дубликаты.
Поэтому установка keep
False даст вам желаемый ответ.
DataFrame.drop_duplicates(*args, **kwargs) Возвращает DataFrame с удаленными дубликатами строк, необязательно только с учетом определенных столбцов
Параметры: подмножество: метка столбца или последовательность меток, необязательно Учитывайте только определенные столбцы для идентификации дубликатов, по умолчанию используйте все столбцы keep: {‘first’, ‘last’, False}, по умолчанию ‘first’ сначала: удалите дубликаты, за исключением первого вхождения. последнее: удалите дубликаты, за исключением последнего вхождения. False: удалите все дубликаты. take_last : устаревшее inplace : boolean, по умолчанию False Следует ли отбрасывать дубликаты на месте или возвращать копию cols: kwargs только аргумент подмножества [устаревший] Возвращает: дедуплицированный: DataFrame
Ответ №3:
Если вы хотите сохранить результат в другом наборе данных:
df.drop_duplicates(keep=False)
или
df.drop_duplicates(keep=False, inplace=False)
Если требуется обновить тот же набор данных:
df.drop_duplicates(keep=False, inplace=True)
Приведенные выше примеры удалят все дубликаты и сохранят один, как DISTINCT *
в SQL
Ответ №4:
используйте groupby
и filter
import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.groupby(["A", "C"]).filter(lambda df:df.shape[0] == 1)
Ответ №5:
Попробуйте эти различные вещи
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar","foo"], "B":[0,1,1,1,1], "C":["A","A","B","A","A"]})
>>>df.drop_duplicates( "A" , keep='first')
или
>>>df.drop_duplicates( keep='first')
или
>>>df.drop_duplicates( keep='last')
Ответ №6:
На самом деле требуется только удаление строк 0 и 1 (сохраняются любые наблюдения, содержащие совпадающие A и C.):
In [335]:
df['AC']=df.A df.C
In [336]:
print df.drop_duplicates('C', take_last=True) #this dataset is a special case, in general, one may need to first drop_duplicates by 'c' and then by 'a'.
A B C AC
2 foo 1 B fooB
3 bar 1 A barA
[2 rows x 4 columns]
Но я подозреваю, что вы действительно хотите этого (сохраняется одно наблюдение, содержащее совпадающие A и C.):
In [337]:
print df.drop_duplicates('AC')
A B C AC
0 foo 0 A fooA
2 foo 1 B fooB
3 bar 1 A barA
[3 rows x 4 columns]
Редактировать:
Теперь это намного понятнее, поэтому:
In [352]:
DG=df.groupby(['A', 'C'])
print pd.concat([DG.get_group(item) for item, value in DG.groups.items() if len(value)==1])
A B C
2 foo 1 B
3 bar 1 A
[2 rows x 3 columns]
Комментарии:
1. Если бы это было то, что я хотел, я бы просто использовал
df.drop_duplicates(['A','C'])
, поскольку значение по умолчанию сохраняет одно наблюдение за первым или последним, как я упоминал в вопросе, — хотя я только что понял, что у меня было неправильное ключевое слово, поскольку я писал из памяти. Я хочу удалить все строки, которые идентичны в интересующих столбцах (A и C в примере данных).