2015-06-11 7 views
13

मैं the docs about slicers एक लाख गुना पढ़ा है, लेकिन यह दौर मेरे सिर कभी नहीं मिला है, इसलिए मैं अभी भी loc उपयोग करने के लिए कैसे एक MultiIndex के साथ एक DataFrame काट करने के लिए यह पता लगाने की कोशिश कर रहा हूँ । यहां तक ​​कि"बहुत अधिक indexers" DataFrame.loc साथ

In [26]: df.loc['A0', :, 'C1', :] 
Out[26]: 
          value 
first second third fourth  
A0 B0  C1 D0   2 
        D1   3 
     B1  C1 D0   10 
        D1   11 

कौन सा भी तीन स्तरों में से चुनाव से काम करता है, और:

      value 
first second third fourth  
A0 B0  C1 D0   2 
        D1   3 
      C3 D0   6 
        D1   7 
     B1  C1 D0   10 
        D1   11 
      C3 D0   14 
        D1   15 
A1 B0  C1 D0   18 
        D1   19 
      C3 D0   22 
        D1   23 
     B1  C1 D0   26 
        D1   27 
      C3 D0   30 
        D1   31 
A2 B0  C1 D0   34 
        D1   35 
      C3 D0   38 
        D1   39 
     B1  C1 D0   42 
        D1   43 
      C3 D0   46 
        D1   47 
A3 B0  C1 D0   50 
        D1   51 
      C3 D0   54 
        D1   55 
     B1  C1 D0   58 
        D1   59 
      C3 D0   62 
        D1   63 

सिर्फ A0 और C1 मानों का चयन करें करने के लिए, मैं कर सकते हैं:

मैं DataFramethis SO answer से साथ शुरू करेंगे tuples के साथ:

In [28]: df.loc['A0', :, ('C1', 'C2'), 'D1'] 
Out[28]: 
          value 
first second third fourth  
A0 B0  C1 D1   3 
      C2 D1   5 
     B1  C1 D1   11 
      C2 D1   13 

अब तक, सहज और शानदार।

तो मैं पहले इंडेक्स स्तर से सभी मूल्यों का चयन क्यों नहीं कर सकता?

In [30]: df.loc[:, :, 'C1', :] 
--------------------------------------------------------------------------- 
IndexingError        Traceback (most recent call last) 
<ipython-input-30-57b56108d941> in <module>() 
----> 1 df.loc[:, :, 'C1', :] 

/usr/local/lib/python2.7/dist-packages/pandas/core/indexing.pyc in __getitem__(self, key) 
    1176  def __getitem__(self, key): 
    1177   if type(key) is tuple: 
-> 1178    return self._getitem_tuple(key) 
    1179   else: 
    1180    return self._getitem_axis(key, axis=0) 

/usr/local/lib/python2.7/dist-packages/pandas/core/indexing.pyc in _getitem_tuple(self, tup) 
    694 
    695   # no multi-index, so validate all of the indexers 
--> 696   self._has_valid_tuple(tup) 
    697 
    698   # ugly hack for GH #836 

/usr/local/lib/python2.7/dist-packages/pandas/core/indexing.pyc in _has_valid_tuple(self, key) 
    125   for i, k in enumerate(key): 
    126    if i >= self.obj.ndim: 
--> 127     raise IndexingError('Too many indexers') 
    128    if not self._has_valid_type(k, i): 
    129     raise ValueError("Location based indexing can only have [%s] " 

IndexingError: Too many indexers 

निश्चित रूप से यह इरादा व्यवहार नहीं है?

नोट: मुझे पता है कि यह df.xs('C1', level='third') के साथ संभव है लेकिन वर्तमान .loc व्यवहार असंगत लगता है।

उत्तर

10

सुरक्षा के लिए (अर्थ में: इस सभी मामलों में काम करेंगे), तो आप सूचकांक करने के लिए दोनों पंक्ति सूचकांक और स्तंभों, जिसके लिए आप pd.IndexSlice उपयोग कर सकते हैं आसानी से ऐसा करने की जरूरत:

In [26]: idx = pd.IndexSlice 

In [27]: df.loc[idx[:, :, 'C1', :],:] 
Out[27]: 
          value 
first second third fourth 
A0 B0  C1 D0   2 
        D1   3 
     B1  C1 D0   10 
        D1   11 
A1 B0  C1 D0   18 
        D1   19 
     B1  C1 D0   26 
        D1   27 
A2 B0  C1 D0   34 
        D1   35 
     B1  C1 D0   42 
        D1   43 
A3 B0  C1 D0   50 
        D1   51 
     B1  C1 D0   58 
        D1   59 

यहाँ idx[:, :, 'C1', :][slice(None), slice(None),'C1', slice(None)] लिखने का एक आसान तरीका है। pd.IndexSlice के बजाय, आप np.s_ का भी उपयोग कर सकते हैं जो थोड़ा छोटा है।

अन्य कारण काम करते हैं, मुझे पूरी तरह से यकीन नहीं है। लेकिन प्रलेखन यहाँ में नोट देखें: http://pandas.pydata.org/pandas-docs/stable/advanced.html#using-slicers (पहले लाल चेतावनी बॉक्स) यह कहा गया है, जहां कि:

आप सूचकांक के लिए और स्तंभों के लिए इंडेक्सर अर्थ .loc विनिर्देशक में सभी कुल्हाड़ियों निर्दिष्ट करना चाहिए। उनके कुछ संदिग्ध मामले हैं जहां पंक्तियों के लिए MuliIndex कहने के बजाय पास किए गए इंडेक्सर को दोनों अक्षों के रूप में गलत तरीके से व्याख्या किया जा सकता है।

+0

यह पहली बार है जब मैंने वास्तव में समझ लिया है कि दस्तावेज़ों का अनुभाग किस बारे में चल रहा है। – LondonRob

4

कारण यह काम नहीं करता है इंडेक्सिंग की अक्ष निर्दिष्ट करने की आवश्यकता से जुड़ा हुआ है (http://pandas.pydata.org/pandas-docs/stable/advanced.html में उल्लिखित)। आपकी समस्या के लिए एक वैकल्पिक समाधान बस यह करने के लिए है:

df.loc(axis=0)[:, :, 'C1', :] 

पांडा कभी कभी भ्रमित हो जाता है जब अनुक्रमित समान हैं या इसी तरह मान हैं। यदि आपके पास 'सी 1' नामक कॉलम होना था या कुछ ऐसा करने के लिए आपको स्लाइसिंग/चयन की इस शैली के तहत ऐसा करने की भी आवश्यकता होगी।

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