Удалить все повторяющиеся строки в Python Pandas

160

pandas drop_duplicatesФункция отлично подходит для «uniquifying» в dataframe. Тем не менее, одним из ключевых аргументов для передачи является 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.

Джейми Булл
источник

Ответы:

235

Теперь это намного проще в пандах с помощью 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)
Бен
источник
2
Что если мои столбцы не помечены явно? Как выбрать столбцы только на основе их индекса?
Хамман Самуил
2
Может быть df.reindex(df.iloc[:,[0,2]].drop_duplicates(keep=False).index)?
Бен
5
Вы могли бы попробоватьdf.drop_duplicates(subset=[df.columns[0:2]], keep = False)
seeiespi
69

Просто хочу добавить ответ Бена на drop_duplicates :

keep : {'first', 'last', False}, по умолчанию 'first'

  • первый: отбросьте дубликаты за исключением первого вхождения.

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

  • False: удалить все дубликаты.

Таким образом, установка keepFalse даст вам желаемый ответ.

DataFrame.drop_duplicates (* args, ** kwargs) Возвращает DataFrame с удаленными дублирующимися строками, опционально только с учетом определенных столбцов

Параметры: subset: метка столбца или последовательность меток, необязательно. Учитывайте только определенные столбцы для определения дубликатов. По умолчанию используются все столбцы keep: {'first', 'last', False}, по умолчанию 'first' first: Удалить дубликаты, кроме за первое вхождение. последний: удалить дубликаты, кроме последнего вхождения. False: удалить все дубликаты. take_last: устарел inplace: логический, по умолчанию False Отбрасывать дубликаты на месте или возвращать копию cols: аргумент только для kwargs подмножества [устарел] Возвраты: дедуплицированный: DataFrame

Джейк
источник
26

Если вы хотите, чтобы результат был сохранен в другом наборе данных:

df.drop_duplicates(keep=False)

или

df.drop_duplicates(keep=False, inplace=False)

Если тот же набор данных необходимо обновить:

df.drop_duplicates(keep=False, inplace=True)

Приведенные выше примеры удаляют все дубликаты и сохраняют один, как DISTINCT *в SQL

Рамануджам Аллам
источник
12

использовать 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)
HYRY
источник
5

На самом деле, удаление строк 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]

Но я подозреваю, что вы действительно хотите этого (одно наблюдение, содержащее совпавшие А и С, сохраняется):

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]
CT Zhu
источник
1
Если бы это было то, что я хотел, я бы просто использовал df.drop_duplicates(['A','C'])в качестве значения по умолчанию, чтобы одно или несколько наблюдений было первым или последним, как я уже упоминал в вопросе - хотя я только что понял, что ключевое слово неправильно, когда я писал по памяти. Я хочу удалить все строки, которые идентичны в интересующих столбцах (A и C в данных примера).
Джейми Булл
0

Попробуйте эти разные вещи

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')
Приянш Гупта
источник