【问题标题】:How to get rid of multilevel index after using pivot table pandas?使用数据透视表熊猫后如何摆脱多级索引?
【发布时间】:2016-12-21 10:31:07
【问题描述】:

我有以下数据框(实际数据框比这个大得多):

sale_user_id    sale_product_id count
1                 1              1
1                 8              1
1                 52             1
1                 312            5
1                 315            1

然后使用以下代码对其进行整形以将 sale_product_id 中的值移动为列标题:

reshaped_df=id_product_count.pivot(index='sale_user_id',columns='sale_product_id',values='count')

得到的数据框是:

sale_product_id -1057   1   2   3   4   5   6   8   9   10  ... 98  980 981 982 983 984 985 986 987 99
sale_user_id                                                                                    
1                NaN    1.0 NaN NaN NaN NaN NaN 1.0 NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3                NaN    1.0 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4                NaN    NaN 1.0 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

如您所见,我们有一个多级索引,我需要的是在第一列中包含 sale_user_is 而没有多级索引:

我采取以下方法:

reshaped_df.reset_index()

结果会是这样,我仍然有 sale_product_id 列,但我不再需要它了:

sale_product_id sale_user_id    -1057   1   2   3   4   5   6   8   9   ... 98  980 981 982 983 984 985 986 987 99
0                          1    NaN 1.0 NaN NaN NaN NaN NaN 1.0 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1                          3    NaN 1.0 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2                          4    NaN NaN 1.0 NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 

我可以对这个数据框进行子集化以摆脱sale_product_id,但我认为它不会有效。我正在寻找一种有效的方法来摆脱多级索引,同时重塑原始数据框

【问题讨论】:

  • 截至 2020 年,解决方案可能是使用 reshaped_df.droplevel(1, axis=0) (documentation),但我不确定我是否完全理解所选答案解决的问题。

标签: python pandas dataframe pivot-table data-analysis


【解决方案1】:

您只需删除index name,使用rename_axispandas 中的新功能0.18.0):

print (reshaped_df)
sale_product_id  1    8    52   312  315
sale_user_id                            
1                  1    1    1    5    1

print (reshaped_df.index.name)
sale_user_id

print (reshaped_df.rename_axis(None))
sale_product_id  1    8    52   312  315
1                  1    1    1    5    1

0.18.00.18.0 下的另一个适用于 pandas 的解决方案:

reshaped_df.index.name = None
print (reshaped_df)

sale_product_id  1    8    52   312  315
1                  1    1    1    5    1

如果还需要删除columns name

print (reshaped_df.columns.name)
sale_product_id

print (reshaped_df.rename_axis(None).rename_axis(None, axis=1))
   1    8    52   312  315
1    1    1    1    5    1

另一种解决方案:

reshaped_df.columns.name = None
reshaped_df.index.name = None
print (reshaped_df)
   1    8    52   312  315
1    1    1    1    5    1

通过评论编辑:

你需要reset_index和参数drop=True:

reshaped_df = reshaped_df.reset_index(drop=True)
print (reshaped_df)
sale_product_id  1    8    52   312  315
0                  1    1    1    5    1

#if need reset index nad remove column name
reshaped_df = reshaped_df.reset_index(drop=True).rename_axis(None, axis=1)
print (reshaped_df)
   1    8    52   312  315
0    1    1    1    5    1

如果需要只删除列名:

reshaped_df = reshaped_df.rename_axis(None, axis=1)
print (reshaped_df)
              1    8    52   312  315
sale_user_id                         
1               1    1    1    5    1

编辑1:

因此,如果需要从 index 创建新列并删除 columns names

reshaped_df =  reshaped_df.rename_axis(None, axis=1).reset_index() 
print (reshaped_df)
   sale_user_id  1  8  52  312  315
0             1  1  1   1    5    1

【讨论】:

  • 我尝试了所有解决方案,实际上前两个解决方案删除 sale_user_id 但我需要它作为第一列,我需要摆脱 sale_product_id。
  • 最后两个解决方案也去掉了 sale_user_id
  • 我认为我们需要添加 reset_index() , reshape_df.rename_axis(None, axis=1).reset_index() 将完全满足我的需求。
【解决方案2】:

它适合我的方式是

df_cross=pd.DataFrame(pd.crosstab(df[c1], df[c2]).to_dict()).reset_index()

【讨论】:

    【解决方案3】:

    制作数据框

    import random
    
    d = {'Country': ['Afghanistan','Albania','Algeria','Andorra','Angola']*2, 
         'Year': [2005]*5 + [2006]*5, 'Value': random.sample(range(1,20),10)}
    df = pd.DataFrame(data=d)
    

    df:

                    Country         Year   Value    
    1               Afghanistan     2005    6
    2               Albania         2005    13
    3               Algeria         2005    10
    4               Andorra         2005    11
    5               Angola          2005    5
    6               Afghanistan     2006    3
    7               Albania         2006    2
    8               Algeria         2006    7
    9               Andorra         2006    3
    10              Angola          2006    6
    

    枢轴

    table = df.pivot(index='Country',columns='Year',values='Value')
    

    表:

    Year    Country         2005    2006
    0       Afghanistan     16      9
    1       Albania         17      19
    2       Algeria         11      7
    3       Andorra         5       12
    4       Angola          6       18
    

    我希望“年份”成为“索引”:

    clean_tbl = table.rename_axis(None, axis=1).reset_index(drop=True)
    

    clean_tbl:

        Country         2005    2006
    0   Afghanistan     16      9
    1   Albania         17      19
    2   Algeria         11      7
    3   Andorra         5       12
    4   Angola          6       18
    

    完成!

    【讨论】:

      【解决方案4】:

      我们需要 reset_index() 将索引列重置回数据帧,然后 rename_axis() 将索引重命名为 None 并将列重命名为它们的 axis=1(列标题)值。

      reshaped_df = reshaped_df.reset_index().rename_axis(None, axis=1)
      

      【讨论】:

        【解决方案5】:

        使用数据透视从长格式转换为宽格式:

        import pandas
        df = pandas.DataFrame({
            "lev1": [1, 1, 1, 2, 2, 2],
            "lev2": [1, 1, 2, 1, 1, 2],
            "lev3": [1, 2, 1, 2, 1, 2],
            "lev4": [1, 2, 3, 4, 5, 6],
            "values": [0, 1, 2, 3, 4, 5]})
        df_wide = df.pivot(index="lev1", columns=["lev2", "lev3"], values="values")
        df_wide
        
        # lev2    1         2
        # lev3    1    2    1    2
        # lev1
        # 1     0.0  1.0  2.0  NaN
        # 2     4.0  3.0  NaN  5.0
        

        重命名(有时令人困惑的)轴名称

        df_wide.rename_axis(columns=[None, None])
        
        #         1         2
        #         1    2    1    2
        # lev1
        # 1     0.0  1.0  2.0  NaN
        # 2     4.0  3.0  NaN  5.0
        

        【讨论】:

          猜你喜欢
          • 2017-11-14
          • 2015-05-11
          • 1970-01-01
          • 2019-12-17
          • 1970-01-01
          • 2018-07-16
          • 1970-01-01
          • 2019-07-26
          • 2018-06-26
          相关资源
          最近更新 更多