如何在pandas DataFrame中展平分层列索引?

7

如果我有一个 pandas.DataFrame,它在列上有一种分层索引,如下所示:

import pandas as pd
columns = pd.MultiIndex.from_product([list('AB'), list('ab')])
df = pd.DataFrame(np.arange(8).reshape((2,4)), columns=columns)
print df

输出[1]:

   A     B   
   a  b  a  b
0  0  1  2  3
1  4  5  6  7

我希望对列索引进行平铺,使其显示如下:
   Aa  Ab  Ba  Bb
0   0   1   2   3
1   4   5   6   7

我尝试过

def flatten(col):
    col.name = ''.join(col.name)
    return col

df.apply(f)

但这忽略了新列的修改名称。

3个回答

21

set_axis

df.set_axis([f"{x}{y}" for x, y in df.columns], axis=1, inplace=False)

   Aa  Ab  Ba  Bb
0   0   1   2   3
1   4   5   6   7

index.map

df.columns = df.columns.map(''.join)
df

   Aa  Ab  Ba  Bb
0   0   1   2   3
1   4   5   6   7

对于非字符串列的值

df.columns = df.columns.map(lambda x: ''.join([*map(str, x)]))
df

   Aa  Ab  Ba  Bb
0   0   1   2   3
1   4   5   6   7

我最喜欢重命名版本,但在0.16.1版本中它对我不起作用。 - snth
我在使用df.columns.map(''.join)时遇到了与int类型的列索引有关的问题。 - Max von Hippel
会去看一下。谢谢你提出来。 - piRSquared
我可能有一个解决方案。看起来列标签可以是int类型。 - dreyco676
1
@dreyco676 当类型为 int 时,解决方案是不同的。 - piRSquared
1
df.columns = (''.join(str(col)) for col in df.columns.values) 看起来能解决问题。 - dreyco676

4
您可以使用列表推导式join来实现:
df.columns = [''.join(col) for col in df.columns]
print (df)
   Aa  Ab  Ba  Bb
0   0   1   2   3
1   4   5   6   7

另一个可能的解决方案:
df.columns = df.columns.to_series().str.join('')
print (df)
   Aa  Ab  Ba  Bb
0   0   1   2   3
1   4   5   6   7

谢谢。这就是我想要的。 - snth
你好,能帮忙回答一下这个问题吗? - Scope

0

以下代码可以正常运行,但会创建一个新的DataFrame

df_flat = pd.DataFrame({''.join(k):v for k,v in df.iteritems()})
print df_flat

输出[3]:

   Aa  Ab  Ba  Bb
0   0   1   2   3
1   4   5   6   7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接