पंडों: एक बहु-स्तरीय स्तंभ सूचकांक से एक स्तर गिरा?


242

यदि मुझे मल्टी-लेवल कॉलम इंडेक्स मिला है:

>>> cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
>>> pd.DataFrame([[1,2], [3,4]], columns=cols)
    ए
   --- + -
    बी | सी
- + --- + -
0 | 1 | 2
1 | 3 | 4

मैं उस सूचकांक के "ए" स्तर को कैसे गिरा सकता हूं, इसलिए मैं इसके साथ समाप्त होता हूं:

    बी | सी
- + --- + -
0 | 1 | 2
1 | 3 | 4

3
यह एक DataFrame विधि है कि दोनों सूचकांक और स्तंभों के लिए करता है अच्छा होगा। इंडेक्स स्तरों को या तो छोड़ने या चुनने का।
सॉरेन

@ सोरेन की जाँच करें stackoverflow.com/a/56080234/3198568droplevelपैरामीटर के माध्यम से कार्य मल्टीलेवल इंडेक्स या कॉलम पर काम कर सकते हैं axis
आइरन

जवाबों:


306

आप उपयोग कर सकते हैं MultiIndex.droplevel:

>>> cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
>>> df = pd.DataFrame([[1,2], [3,4]], columns=cols)
>>> df
   a   
   b  c
0  1  2
1  3  4

[2 rows x 2 columns]
>>> df.columns = df.columns.droplevel()
>>> df
   b  c
0  1  2
1  3  4

[2 rows x 2 columns]

55
यह स्पष्ट रूप से कहना सबसे अच्छा है कि किस स्तर को गिराया जा रहा है। स्तर 0-अनुक्रमित शीर्ष से शुरू होते हैं। >>> df.columns = df.columns.droplevel(0)
टेड पेट्रोव

6
यदि आप जिस इंडेक्स को छोड़ने का प्रयास कर रहे हैं, वह बाईं ओर (पंक्ति) तरफ है और शीर्ष (कॉलम) की तरफ नहीं है, तो आप "कॉलम" को "इंडेक्स" में बदल सकते हैं और उसी विधि का उपयोग कर सकते हैं:>>> df.index = df.index.droplevel(1)
इडोडो

7
पांडा संस्करण 0.23.4 में, df.columns.droplevel()अब उपलब्ध नहीं है।
योन्घम

8
@yoonghm यह वहां है, आप शायद इसे केवल उन कॉलमों पर बुला रहे हैं जिनमें बहु-सूचकांक नहीं है
मैट हैरिसन

1
मेरे पास तीन स्तर गहरे थे और केवल मध्य स्तर तक गिरना चाहते थे। मैंने पाया कि सबसे कम (स्तर [2]) और फिर उच्चतम (स्तर [0]) ने सबसे अच्छा काम किया। >>>df.columns = df.columns.droplevel(2) >>>df.columns = df.columns.droplevel(0)
काइल सी

65

सूची को समझने के लिए सूचकांक को छोड़ने का एक और तरीका है:

df.columns = [col[1] for col in df.columns]

   b  c
0  1  2
1  3  4

यह रणनीति भी उपयोगी है यदि आप दोनों स्तरों से नामों को संयोजित करना चाहते हैं जैसे नीचे दिए गए उदाहरण में जहां नीचे के स्तर में दो 'y's शामिल हैं:

cols = pd.MultiIndex.from_tuples([("A", "x"), ("A", "y"), ("B", "y")])
df = pd.DataFrame([[1,2, 8 ], [3,4, 9]], columns=cols)

   A     B
   x  y  y
0  1  2  8
1  3  4  9

शीर्ष स्तर छोड़ने से सूचकांक 'y' के साथ दो कॉलम निकल जाएंगे। सूची की समझ के साथ नामों को जोड़कर इससे बचा जा सकता है।

df.columns = ['_'.join(col) for col in df.columns]

    A_x A_y B_y
0   1   2   8
1   3   4   9

यह एक समस्या है जो मुझे एक ग्रुपबी करने के बाद हुई और इसे हल करने वाले इस अन्य प्रश्न को खोजने में थोड़ा समय लगा । मैंने उस समाधान को यहाँ के विशिष्ट मामले में बदल दिया।


2
[col[1] for col in df.columns]अधिक सीधे है df.columns.get_level_values(1)
एरिक ओ लेबिगॉट

2
इसी तरह की आवश्यकता थी जिसमें कुछ कॉलमों में खाली स्तर के मान थे। निम्नलिखित का प्रयोग करें:[col[0] if col[1] == '' else col[1] for col in df.columns]
लोगन

43

ऐसा करने का दूसरा तरीका .xs विधि का उपयोग करके, dfक्रॉस सेक्शन के आधार पर पुन: असाइन करना है ।df

>>> df

    a
    b   c
0   1   2
1   3   4

>>> df = df.xs('a', axis=1, drop_level=True)

    # 'a' : key on which to get cross section
    # axis=1 : get cross section of column
    # drop_level=True : returns cross section without the multilevel index

>>> df

    b   c
0   1   2
1   3   4

1
यह केवल तभी काम करता है जब संपूर्ण स्तंभ स्तर के लिए एकल लेबल होता है।
टेड पेट्रोउ

1
जब आप दूसरे स्तर को गिराना चाहते हैं तो काम नहीं करता है।
सॉरेन

यदि आप स्लाइस और समान स्तर के लिए छोड़ना चाहते हैं तो यह एक अच्छा समाधान है। यदि आप दूसरे स्तर पर स्लाइस करना चाहते हैं (कहते हैं b) तो उस स्तर को छोड़ दें और पहले स्तर ( a) के साथ छोड़ दें , निम्नलिखित काम करेगा:df = df.xs('b', axis=1, level=1, drop_level=True)
टिफ़नी जी। विल्सन

27

पंडों के रूप में 0.24.0 , अब हम DataFrame.droplevel () का उपयोग कर सकते हैं :

cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
df = pd.DataFrame([[1,2], [3,4]], columns=cols)

df.droplevel(0, axis=1) 

#   b  c
#0  1  2
#1  3  4

यदि आप अपना डेटाफ़्रेम विधि-श्रृंखला रोलिंग रखना चाहते हैं तो यह बहुत उपयोगी है।


यह "शुद्धतम" समाधान है जिसमें एक नया डेटाफ़्रेम लौटाया गया है न कि इसे "स्थान पर" संशोधित किया गया है।
एलियाडल

16

आप स्तंभों का नाम बदलकर भी इसे प्राप्त कर सकते हैं:

df.columns = ['a', 'b']

इसमें एक मैनुअल कदम शामिल है, लेकिन एक विकल्प हो सकता है खासकर यदि आप अंततः अपने डेटा फ्रेम का नाम बदल देंगे।


यह अनिवार्य रूप से मिंट का पहला जवाब है। अब, नामों की सूची (जो आमतौर पर थकाऊ है) निर्दिष्ट करने की आवश्यकता नहीं है, क्योंकि यह आपके द्वारा दिया गया है df.columns.get_level_values(1)
एरिक ओ लेबिगॉट

13

sum स्तर = 1 के साथ एक छोटी सी चाल (काम जब स्तर = 1 सभी अद्वितीय है)

df.sum(level=1,axis=1)
Out[202]: 
   b  c
0  1  2
1  3  4

अधिक सामान्य समाधान get_level_values

df.columns=df.columns.get_level_values(1)
df
Out[206]: 
   b  c
0  1  2
1  3  4

4

मुझे इस समस्या से जूझना पड़ा है क्योंकि मुझे नहीं पता कि मेरी छोटी बूंद () फ़ंक्शन काम नहीं करता है। कई के माध्यम से काम करें और जानें कि आपकी तालिका में 'ए' कॉलम नाम है और 'बी', 'सी' इंडेक्स हैं। ऐसे करें मदद मिलेगी

df.columns.name = None
df.reset_index() #make index become label

1
यह वांछित आउटपुट को पुन: उत्पन्न नहीं करता है।
एरिक ओ लेबिगॉट

यह पोस्ट किए जाने की तिथि के आधार पर, पंडों के आपके संस्करण में ड्रॉप स्तर शामिल नहीं हो सकता है (इसे जनवरी 2019 को स्थिर संस्करण में जोड़ा गया था, 24.0)
LinkBerest
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.