2013-07-04 2 views
10

Я хотел бы, чтобы полностью удалить уровень из 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)] 

Я хотел бы, чтобы извлечь первые 2 уровня, для достижения:

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

droplevel капель уровень сохраняется, но сохраняется дубликат:

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

Я мог бы в принципе рассчитывать l unique, чтобы удалить их. Однако это не выглядит правильным. Есть ли более прямой метод?

ответ

7

Это может быть повышение к droplevel, возможно, передавая uniquify=True

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

Вот еще один способ сделать это

Сначала создайте некоторые данные

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 

Метод, показанный выше

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

Давайте расколоть индекс, кроме 2-х компонентов, l1 и l2 и uniquify, гораздо быстрее уникальной их, поскольку они являются 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 

Сборку

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 

Общее время около 270ms, довольно хороший ускорение. Обратите внимание: я думаю, что порядок может быть другим, но я думаю, что некоторая комбинация np.repeate/np.tile будет работать

+0

Еще одна идея может быть улучшением уникальности для возврата объекта того же класса. –

+0

Спасибо, однако мне интересно, есть ли лучшее решение, которое не требует запуска 'unique', что довольно дорого. В конце концов я просто хочу как-то извлечь 2 уровня из 3 в 'MultiIndex', а не создать новый объект. –

+0

уникально на самом деле довольно быстро здесь; Какова ваша конечная цель? – Jeff

Смежные вопросы