2013-07-04 14 views
10

ja jak całkowicie usunąć poziomu ze MultiIndexUsuwanie poziomu ze pand MultiIndex

import pandas as pd 
tuples = [(0, 100, 1000),(0, 100, 1001),(0, 100, 1002), (1, 101, 1001)] 
index_3levels=pd.MultiIndex.from_tuples(tuples,names=["l1","l2","l3"]) 
print index_3levels.levels 
[Int64Index([0, 1], dtype=int64), Int64Index([100, 101], dtype=int64), Int64Index([1000, 1001, 1002], dtype=int64)] 

ja do ekstrakcji 2 pierwszych poziomów osiągnąć:

print index_2levels 
MultiIndex 
[(0, 100), (1, 101)] 

droplevel kropli poziom, ale zachowuje duplikaty:

print index_3levels.droplevel("l3") 
MultiIndex 
[(0, 100), (0, 100), (0, 100), (1, 101)] 

Mogłem w zasadzie cal l unique, aby je usunąć. Jednak nie wygląda to na właściwe podejście. Czy istnieje bardziej bezpośrednia metoda?

Odpowiedz

7

To może być rozszerzeniem droplevel, może przekazując uniquify=True

In [77]: MultiIndex.from_tuples(index_3levels.droplevel('l3').unique()) 
Out[77]: 
MultiIndex 
[(0, 100), (1, 101)] 

Oto kolejny sposób to zrobić

Najpierw utwórz niektóre dane

In [226]: def f(i): 
      return [(i,100,1000),(i,100,1001),(i,100,1002),(i+1,101,1001)] 

In [227]: l = [] 

In [228]: for i in range(1000000): 
      l.extend(f(i)) 

In [229]: index_3levels=pd.MultiIndex.from_tuples(l,names=["l1","l2","l3"]) 

In [230]: len(index_3levels) 
Out[230]: 4000000 

sposób przedstawiony powyżej

In [238]: %timeit MultiIndex.from_tuples(index_3levels.droplevel(level='l3').unique()) 
1 loops, best of 3: 2.26 s per loop 

Niech podzielić indeks oprócz 2 komponentów, L1 i L2 i uniquify znacznie szybciej wyjątkowy nich, ponieważ są one Int64Index

In [249]: l2 = index_3levels.droplevel(level='l3').droplevel(level='l1').unique() 

In [250]: %timeit index_3levels.droplevel(level='l3').droplevel(level='l1').unique() 
10 loops, best of 3: 35.3 ms per loop 

In [251]: l1 = index_3levels.droplevel(level='l3').droplevel(level='l2').unique() 

In [252]: %timeit index_3levels.droplevel(level='l3').droplevel(level='l2').unique() 
10 loops, best of 3: 52.2 ms per loop 

In [253]: len(l1) 
Out[253]: 1000001 

In [254]: len(l2) 
Out[254]: 2 

Zamontować

In [255]: %timeit MultiIndex.from_arrays([ np.repeat(l1,len(l2)), np.repeat(l2,len(l1)) ]) 
10 loops, best of 3: 183 ms per loop 

Łączny czas około 270 ms, ładna dobre przyspieszenie. Zauważ, że myślę, że kolejność może być inna, ale myślę, że jakaś kombinacja np.repeate/np.tile zadziała

+0

Innym pomysłem może być ulepszenie unikalne dla obiektu powrotu tej samej klasy. –

+0

Dzięki, ale zastanawiam się, czy istnieje lepsze rozwiązanie, które nie wymaga uruchomienia 'unique', co jest dość drogie. Poza tym po prostu chcę jakoś wyodrębnić 2 poziomy 3 w 'MultiIndex', nie tworzyć nowego obiektu. –

+0

Unique jest tutaj dość szybki; jaki jest twój ostateczny cel? – Jeff

Powiązane problemy