Подтвердить что ты не робот

Pandas: получить дублированные индексы

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

В частности, у меня есть этот dataframe:

import pandas as pd
wget https://www.dropbox.com/s/vmimze2g4lt4ud3/alt_exon_repeatmasker_intersect.bed
alt_exon_repeatmasker = pd.read_table('alt_exon_repeatmasker_intersect.bed', header=None, index_col=3)

In [74]: alt_exon_repeatmasker.index.is_unique
Out[74]: False

И некоторые индексы имеют повторяющиеся значения в 9-м столбце (тип повторяющегося элемента ДНК в этом месте), и я хочу знать, каковы различные типы повторяющихся элементов для отдельных местоположений (каждый индекс = местоположение генома).

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

Чтобы упростить еще больше, если у нас есть только индекс и тип повтора,

genome_location1    MIR3
genome_location1    AluJb
genome_location2    Tigger1
genome_location3    AT_rich

Таким образом, я хотел бы видеть все повторяющиеся индексы и их повторяющиеся типы:

genome_location1    MIR3
genome_location1    AluJb

EDIT: добавленный пример игрушки

4b9b3361

Ответ 1

df.groupby(level=0).filter(lambda x: len(x) > 1)['type']

Мы добавили метод filter для такого рода операций. Вы также можете использовать маскирование и преобразование для эквивалентных результатов, но это быстрее и немного более читаемо.

Важно:

Метод filter был введен в версии 0.12, но он не работал в DataFrames/Series с неинициализированными индексами. Проблема - и связанная с ней проблема с transform на Series - была исправлена ​​для версии 0.13, которая должна быть выпущена в любой день.

Понятно, что суть этого вопроса - ненуковые индексы, поэтому я должен указать, что этот подход не поможет, пока у вас не будет pandas 0.13. В то же время обходной путь transform - это путь. Будьте уверены, что если вы попробуете это на Серии с неидеальным индексом, это тоже потерпит неудачу.

Нет веской причины, по которой filter и transform не должны применяться к неинициальным индексам; сначала он был плохо реализован.

Ответ 2

Также полезно и очень кратко:

df[df.index.duplicated()]

Обратите внимание, что это возвращает только одну из дублированных строк, поэтому, чтобы увидеть все дублированные строки, вам нужно следующее:

df[df.index.duplicated(keep=False)]

Ответ 3

>>> df[df.groupby(level=0).transform(len)['type'] > 1]
                   type
genome_location1   MIR3
genome_location1  AluJb

Ответ 4

Еще быстрее и лучше:

df.index.get_duplicates()

Ответ 5

Более кратко:

df[df.groupby(level=0).type.count() > 1]

FYI мультииндекс:

df[df.groupby(level=[0,1]).type.count() > 1]