2014-03-06 111 views
89

如果我有一個多層次的列索引:熊貓:從多級索引中刪除一個級別?

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

我怎麼能丟棄指數的「一」的水平,所以我結束了:

 
    b | c 
--+---+-- 
0 | 1 | 2 
1 | 3 | 4 

回答

124

你可以使用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] 
+14

這可能是最好的明確說出哪個級別被丟棄。級別從頂部開始爲0索引。 '>>> df.columns = df.columns.droplevel(0)' –

10

你也可以通過重命名列來實現:

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

這涉及到手動工序,但可能是特別是如果你最終會重命名您的數據幀的選項。

20

另一種方法是使用.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 
+0

這也適用於鏈接! –

+0

只有在整個列級別存在單個標籤時才能使用。 –

15

另一種方式來刪除該索引是使用列表理解:

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

    b c 
0 1 2 
1 3 4 

這種策略也非常有用,如果你想從兩個層面的名字下面,其中底部的例子結合起來像級別包含兩個'y':

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 

這是一個問題,我做了GROUPBY後出現,並花了一段時間才能找到this other question是解決它。我在這裏調整了解決方案的具體情況。

0

我一直在努力解決這個問題,因爲我不知道爲什麼我的droplevel()函數不起作用。通過幾個工作,並瞭解到表中的'a'是列名和'b','c'是索引。像這樣做會有幫助

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