Pandas: Obțineți indici duplicați (Programare, Python, Indexare, Pandas)

Olga Botvinnik a intrebat.
a intrebat.

Având în vedere un cadru de date, vreau să obțin indicii duplicați, care nu au valori duplicate în coloane, și să văd care valori sunt diferite.

Mai exact, am acest cadru de date:

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

Iar unii dintre indici au valori duplicate în coloana a 9-a (tipul de element repetitiv de ADN în această locație) și vreau să știu care sunt diferitele tipuri de elemente repetitive pentru locațiile individuale (fiecare indice = o locație a genomului).

Bănuiesc că acest lucru va necesita un fel de groupby și, sperăm, ceva groupby ninja mă poate ajuta.

Pentru a simplifica și mai mult, dacă avem doar indicele și tipul de repetiție,

genome_location1    MIR3
genome_location1    AluJb
genome_location2    Tigger1
genome_location3    AT_rich

Deci, la ieșire aș dori să văd toți indicii duplicați și tipurile lor de repetiție, ca atare:

genome_location1    MIR3
genome_location1    AluJb

EDIT: am adăugat un exemplu de jucărie

Comentarii

  • Bună ziua, de obicei este o bună practică să simplificăm întrebarea cât mai mult posibil și să creăm un exemplu de jucărie cu intrare și ieșire dorită. La astfel de întrebări se răspunde mult mai repede și va fi util pentru viitorii cititori. –  > Por Roman Pekar.
6 răspunsuri
Dan Allan
df.groupby(level=0).filter(lambda x: len(x) > 1)['type']

Am adăugat filter metoda pentru acest tip de operațiune. Poți folosi și mascarea și transformarea pentru rezultate echivalente, dar aceasta este mai rapidă și puțin mai ușor de citit.

Important:

Adresa filter a fost introdusă în versiunea 0.12, dar nu a funcționat în cazul DataFrames/Series cu indici neunici. Această problemă – și o problemă legată de transform pe Series — a fost rezolvată pentru versiunea 0.13, care ar trebui să fie lansată în orice zi.

În mod clar, indicii neunicipați reprezintă miezul acestei întrebări, așa că ar trebui să subliniez că această abordare nu vă va ajuta până când nu aveți pandas 0.13. Între timp, aplicația transform soluția de rezolvare este cea mai bună cale de urmat. Fiți atenți că, dacă încercați acest lucru pe un fișier Serie cu un index neunic, va eșua și ea.

Nu există niciun motiv întemeiat pentru care filter și transform nu ar trebui să se aplice la indici neunici; pur și simplu a fost implementat greșit la început.

Comentarii

  • acesta nu funcționează pentru mine, am încercat chiar și df.groupby(level=0).filter(lambda x: True), primind Exception: Reindexing only valid with uniquely valued Index objects. –  > Por Roman Pekar.
  • Bună captură! Această utilizare particulară întâmpină un bug care a fost rezolvat pentru v0.13, pe care evident mulți utilizatori nu îl au. Răspuns actualizat. –  > Por Dan Allan.
  • Mulțumesc! Sunt încă pe 0.12 și voi rămâne la ea până când v0.13 este complet lansată, deoarece împart o bază de cod și virtualenv încurcă totul pentru mine. Voi trece la asta odată ce vom face upgrade! Mulțumesc! Am folosit pandas timp de un an, dar încă mă mai gândesc la groupbys –  > Por Olga Botvinnik.
  • Dacă ne uităm la eficiență, mă îndoiesc că este mai rapid decât df.set_index('type').index.duplicates – deoarece trebuie să parcurgă fiecare grup în parte pentru a performa, în loc să se uite la el „din afara grupurilor”. –  > Por FooBar.
  • Nu am știut despre index.duplicates. Adăugați-l ca răspuns; este cu siguranță mai bine. –  > Por Dan Allan.
Matthew

De asemenea, util și foarte succint:

df[df.index.duplicated()]

Rețineți că acest lucru returnează doar unul dintre rândurile duplicate, așa că pentru a vedea toate rândurile duplicate, veți dori acest lucru:

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

Comentarii

  • Există un exemplu excelent în docs –  > Por agent18.
  • Exemplu de utilizare: 1. idx = pd.Index(['lama', 'cow', 'lama', 'beetle', 'lama']) 2. idx.duplicated() 3. array([False, False, True, False, True]) –  > Por agent18.
feetwet

Chiar mai rapid și mai bine:

df.index.get_duplicates()

Comentarii

  • răspuns bun, dar vine cu o avertizare pentru pandas 0.23.4. 'get_duplicates' is deprecated and will be removed in a future release. You can use idx[idx.duplicated()].unique() instead –  > Por Ali Faizan.
Roman Pekar
>>> df[df.groupby(level=0).transform(len)['type'] > 1]
                   type
genome_location1   MIR3
genome_location1  AluJb

Comentarii

  • sau, foarte asemănător, cu filter ca și cum ar fi așa: df.groupby(level=0).filter(lambda x: len(x) > 1)['type']. Va fi mai rapid decât transformarea și mascarea. –  > Por Dan Allan.
  • @DanAllan grozav, poate mai adaugi un răspuns și OP îl va accepta? –  > Por Roman Pekar.
  • Mulțumesc! Voi accepta acest răspuns, deoarece este garantat să funcționeze cu versiunea actuală a pandas. –  > Por Olga Botvinnik.
  • Cred că aceasta este alegerea corectă. O conversație utilă, în general. –  > Por Dan Allan.
Jwok

La data de 21.09.18 Pandas indică FutureWarning: 'get_duplicates' is deprecated and will be removed in a future release, sugerând în schimb următoarele:

df.index[df.index.duplicated()].unique()

Fil

Mai pe scurt: Fil:

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

FYI un multi-index:

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