将Pandas Multi-Index变成列

时间:2013-11-21 00:37:03

标签: python pandas dataframe flatten multi-index

我有一个包含2个索引级别的数据框:

                         value
Trial    measurement
    1              0        13
                   1         3
                   2         4
    2              0       NaN
                   1        12
    3              0        34 

我想谈谈这个:

Trial    measurement       value

    1              0        13
    1              1         3
    1              2         4
    2              0       NaN
    2              1        12
    3              0        34 

我怎样才能做到最好?

我需要这个,因为我想聚合数据as instructed here,但如果它们被用作索引,我就无法选择我的列。

5 个答案:

答案 0 :(得分:142)

reset_index()是一个pandas DataFrame方法,它将索引值作为列传输到DataFrame中。参数的默认设置是 drop = False (这会将索引值保留为列)。

您只需在DataFrame的名称后面添加.reset_index(inplace=True)

df.reset_index(inplace=True)  

答案 1 :(得分:15)

这并不适用于你的情况,但它可能对其他人(比如我5分钟前)有所帮助。如果一个人的多索引具有相同的名称:

                         value
Trial        Trial
    1              0        13
                   1         3
                   2         4
    2              0       NaN
                   1        12
    3              0        34 

df.reset_index(inplace=True)将失败,因为创建的列无法共享名称。

那么你需要用df.index = df.index.set_names(['Trial', 'measurement'])重命名多索引来获得:

                           value
Trial    measurement       

    1              0        13
    1              1         3
    1              2         4
    2              0       NaN
    2              1        12
    3              0        34 

然后df.reset_index(inplace=True)会像魅力一样发挥作用。

我在名为live_date的datetime-column(而不是索引)上按年和月分组后遇到此问题,这意味着年份和月份都被命名为live_date

答案 2 :(得分:3)

在某些情况下,无法使用df.reset_index()(例如,当您也需要索引时)。在这种情况下,请使用index.get_level_values()直接访问索引值:

df['Trial'] = df.index.get_level_values(0)
df['measurement'] = df.index.get_level_values(1)

这会将索引值分配给各个列,并且保留索引。

有关更多信息,请参见docs

答案 3 :(得分:0)

如评论中提到的@ cs95,仅下降一个级别,请使用:

df.reset_index(level=[...])

这避免了重置后必须重新定义所需的索引。

答案 4 :(得分:0)

我也遇到了卡尔的问题。我只是发现自己重命名了聚合列,然后重置了索引。

df = pd.DataFrame(df.groupby(['arms', 'success'])['success'].sum()).rename(columns={'success':'sum'})

enter image description here

df = df.reset_index()

enter image description here