python Pandas:从多级列索引中删除一个级别?

8hhllhi2  于 2023-03-21  发布在  Python
关注(0)|答案(8)|浏览(136)

如果我有一个多级列索引:

>>> 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

我怎样才能把那个指数的“a”级降下来,所以我最后得到:

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

ni65a41a1#

您可以使用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]
5gfr0r5j

5gfr0r5j2#

从Pandas0.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

如果您希望保持DataFrame方法链滚动,这将非常有用。

t0ybt7op

t0ybt7op3#

删除索引的另一种方法是使用列表解析:

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

pgx2nnw8

pgx2nnw84#

另一种方法是使用.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
py49o6xq

py49o6xq5#

使用sum和level=1的一个小技巧(当level=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
7z5jn7bk

7z5jn7bk6#

您也可以通过重命名列来实现这一点:
df.columns = ['a', 'b']
这涉及手动步骤,但可能是一个选项,尤其是在最终重命名数据框时。

im9ewurl

im9ewurl7#

我一直在努力解决这个问题,因为我不知道为什么我的droplevel()函数不起作用。通过几个工作,了解表中的'a'是列名,'b','c'是索引。这样做会有所帮助。

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

cqoc49vn8#

new_columns_cdnr = []
for column in list(df.columns):
    new = [x for x in list(column) if not 'unnamed' in x.lower()]
    new_columns_cdnr.append(new[-1])
df.columns = new_columns_cdnr

相关问题