2013-07-04 26 views
10

से एक स्तर निकालें मैं पूरी तरह से एक MultiIndexएक पांडा 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)] 

मैं सिद्धांत रूप से कैल में कर सकता था एल 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 घटक, एल 1, और एल 2 और 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

धन्यवाद, हालांकि मुझे आश्चर्य है कि कोई बेहतर समाधान है, जिसके लिए 'अद्वितीय' चलने की आवश्यकता नहीं है जो कि बहुत महंगा है। आखिर में मैं किसी भी तरह से 'मल्टीइंडेक्स' में 3 के 2 स्तर निकालने के लिए, एक नई वस्तु नहीं बनाना चाहता हूं। –

+0

अद्वितीय वास्तव में यहां बहुत तेज़ है; आपका अंतिम लक्ष्य क्या है? – Jeff

संबंधित मुद्दे