2013-03-17 2 views
15

मैं के साथ (समय, टिकर) Multiindex और बोली/पूछना/आदि डेटा स्तंभ एक DataFrame "df" है का चयन करें:एक DataFrame से एक बहु-कुंजी क्रॉस सेक्शन

 

          tod last  bid  ask  volume 
    time  ticker     
    2013-02-01 SPY  1600 149.70 150.14 150.17 1300 
       SLV  1600 30.44 30.38 30.43 3892 
       GLD  1600 161.20 161.19 161.21 3860 

मैं एक दूसरे का चयन करना चाहते हैं -लेवल (स्तर = 1) एकाधिक कुंजी का उपयोग कर क्रॉस सेक्शन। अभी, मैं इसे एक कुंजी का उपयोग कर कर सकता हूं, यानी

 

    df.xs('SPY', level=1) 

जो मुझे SPY की एक टाइमरीज़ देता है।

 

    df.xs(['SPY', 'GLD'], level=1) 

: एक बहु कुंजी पार अनुभाग में, दोनों जासूसी GLD की अर्थात एक संयुक्त पार अनुभाग, की तरह कुछ का चयन करने के लिए सबसे अच्छा तरीका क्या है?

उत्तर

5

एक पैनल में बदलें, तो अनुक्रमण प्रत्यक्ष

In [20]: df = pd.DataFrame(dict(time = pd.Timestamp('20130102'), 
           A = np.random.rand(3), 
       ticker=['SPY','SLV','GLD'])).set_index(['time','ticker']) 

In [21]: df 
Out[21]: 
          A 
time  ticker   
2013-01-02 SPY  0.347209 
      SLV  0.034832 
      GLD  0.280951 

In [22]: p = df.to_panel() 

In [23]: p 
Out[23]: 
<class 'pandas.core.panel.Panel'> 
Dimensions: 1 (items) x 1 (major_axis) x 3 (minor_axis) 
Items axis: A to A 
Major_axis axis: 2013-01-02 00:00:00 to 2013-01-02 00:00:00 
Minor_axis axis: GLD to SPY 

In [24]: p.ix[:,:,['SPY','GLD']] 
Out[24]: 
<class 'pandas.core.panel.Panel'> 
Dimensions: 1 (items) x 1 (major_axis) x 2 (minor_axis) 
Items axis: A to A 
Major_axis axis: 2013-01-02 00:00:00 to 2013-01-02 00:00:00 
Minor_axis axis: SPY to GLD 
7

मैं एक और अधिक प्रत्यक्ष select का उपयोग करने से दूसरा रास्ता नहीं मिल सका:

>>> df 

     last tod 
A SPY  1 1600 
    SLV  2 1600 
    GLD  3 1600 

>>> df.select(lambda x: x[1] in ['SPY','GLD']) 

     last tod 
A SPY  1 1600 
    GLD  3 1600 
+2

अच्छा, यह शायद सबसे आसान तरीका है। मुझे आश्चर्य है कि यह सबसे कुशल है, हालांकि प्रत्येक पंक्ति के लिए लैम्ब्डा को कॉल करना धीमा हो सकता है, लेकिन फिर मुझे यकीन नहीं है कि मौजूदा संस्करण –

+0

में एक तेज़ तरीका है या नहीं, क्या आप उपरोक्त पैनल समाधान देखते हैं? अगर किसी भी तरह के गैर-तुच्छ फ्रेम – Jeff

+1

के लिए बहुत अक्षम है तो वास्तव में पैनल अधिक समझ में आता है, और बहुत तेज़ है। धन्यवाद! –

1

क्या इसके लायक है के लिए है, मैंने किया था निम्नलिखित:

foo = pd.DataFrame(np.random.rand(12,3), 
        index=pd.MultiIndex.from_product([['A','B','C','D'],['Green','Red','Blue']], 
                names=['Letter','Color']), 
        columns=['X','Y','Z']).sort_index() 

foo.reset_index()\ 
    .loc[foo.reset_index().Color.isin({'Green','Red'})]\ 
    .set_index(foo.index.names) 

यह दृष्टिकोण चुनने के समान है, लेकिन लैम्ब्डा के साथ सभी पंक्तियों पर पुनरावृत्ति से बचाता है।

हालांकि, मैं पैनल दृष्टिकोण को यह तुलना में, और ऐसा लगता है पैनल समाधान तेजी से (सूचकांक के लिए 2.91 एमएस/loc to_panel/to_frame के लिए 1.48 एमएस बनाम है:

foo.to_panel()[:,:,['Green','Red']].to_frame() 

टाइम्स:

In [56]: 
%%timeit 
foo.reset_index().loc[foo.reset_index().Color.isin({'Green','Red'})].set_index(foo.index.names) 
100 loops, best of 3: 2.91 ms per loop 

In [57]: 
%%timeit 
foo2 = foo.reset_index() 
foo2.loc[foo2.Color.eq('Green') | foo2.Color.eq('Red')].set_index(foo.index.names) 
100 loops, best of 3: 2.85 ms per loop 

In [58]: 
%%timeit 
foo2 = foo.reset_index() 
foo2.loc[foo2.Color.ne('Blue')].set_index(foo.index.names) 
100 loops, best of 3: 2.37 ms per loop 

In [54]: 
%%timeit 
foo.to_panel()[:,:,['Green','Red']].to_frame() 
1000 loops, best of 3: 1.18 ms per loop 

0123:

अद्यतन

इस विषय (फिर) की समीक्षा के बाद, मैं निम्नलिखित मनाया

In [100]: 
%%timeit 
foo2 = pd.DataFrame({k: foo.loc[k] for k in foo.index if k[1] in ['Green','Red']}).transpose() 
foo2.index.names = foo.index.names 
foo2.columns.names = foo2.columns.names 
100 loops, best of 3: 1.97 ms per loop 

In [101]: 
%%timeit 
foo2 = pd.DataFrame.from_dict({k: foo.loc[k] for k in foo.index if k[1] in ['Green','Red']}, orient='index') 
foo2.index.names = foo.index.names 
foo2.columns.names = foo2.columns.names 
100 loops, best of 3: 1.82 ms per loop 

आप मूल आदेश और स्तरों के नामकरण के संरक्षण के बारे में परवाह नहीं है, तो आप उपयोग कर सकते हैं:

%%timeit 
pd.concat({key: foo.xs(key, axis=0, level=1) for key in ['Green','Red']}, axis=0) 
1000 loops, best of 3: 1.31 ms per loop 

और अगर आप सिर्फ पहली स्तर पर चयन कर रहे हैं:

%%timeit 
pd.concat({key: foo.loc[key] for key in ['A','B']}, axis=0, names=foo.index.names) 
1000 loops, best of 3: 1.12 ms per loop 

बनाम:

%%timeit 
foo.to_panel()[:,['A','B'],:].to_frame() 
1000 loops, best of 3: 1.16 ms per loop 

एक और अद्यतन

आप उदाहरण foo के सूचकांक को सॉर्ट करते हैं, तो कई बार कई ऊपर (बार एक पूर्व सॉर्ट किया सूचकांक के अनुसार अपडेट कर दिया गया है) में सुधार होगा। हालांकि, जब सूचकांक क्रमबद्ध हो जाता है, तो आप समाधान user674155 द्वारा वर्णित का उपयोग कर सकते हैं:

%%timeit 
foo.loc[(slice(None), ['Blue','Red']),:] 
1000 loops, best of 3: 582 µs per loop 

यह सबसे अधिक कुशल और मेरी राय में सहज है (उपयोगकर्ता पैनल को समझने की जरूरत नहीं है और वे से कैसे बनाए जाते हैं फ्रेम)।

नोट: यहां तक ​​कि अगर सूचकांक को अभी तक हल नहीं किया गया है, तो फ्लाई पर foo की अनुक्रमणिका को सॉर्ट करना to_panel विकल्प के प्रदर्शन में तुलनीय है।

regression_df.loc[(slice(None), ['SPY', 'GLD']), :] 

यह दृष्टिकोण की आवश्यकता है कि सूचकांक कोषगत अनुसार क्रमबद्ध हो (df.sort_index() का उपयोग करें):

3

वहाँ पांडा के नवीनतम संस्करण के साथ ऐसा करने का बेहतर तरीके हैं।

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