Ответ 1
Это может быть улучшением до 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
Пусть разделить индекс на две компоненты, l1 и l2 и однозначно идентифицировать, быстрее, чем уникальные, поскольку это 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
Общее время около 270 мс, довольно хорошее ускорение. Обратите внимание: я думаю, что порядок может быть другим, но я думаю, что некоторая комбинация np.repeate/np.tile будет работать