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: добавленный пример игрушки
Ответы
Ответ 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]