【问题标题】:How to groupby column and then reorder columns within groups in python如何按列分组,然后在python中的组内重新排序列
【发布时间】:2022-01-02 14:40:54
【问题描述】:

我有以下分组数据框:

                 Value1      Value2

    Category   
------------------------------------   
0          0         62          44 
           1         55          46 
           2         73          75 
1          0         61          49 
           1         55          46 
           2         34          35  
2          0         62          48 
           1         55          46 
           2         44          25 

我想为每个组将“Value1”列重新排序为升序,同时保持“Category”列的顺序。目标是“类别”0 将对应于最低的“Value1”值,“类别”5 将对应于最高的“Value1”值。 “Value2”值将对应于它们对应的原始“Value1”值。这是我要生成的输出数据框:

                 Value1      Value2

    Category   
------------------------------------   
0          0         55          46    
           1         62          44
           2         73          75                 
1          0         34          35
           1         55          46  
           2         61          49
2          0         44          25
           1         55          46 
           2         62          48

如何在 python 中完成此操作?我尝试过使用.reset_index() 和`.sort_values(),但我只是没有得到我想要的分组数据框。我试过了:

df.sort_values(['Value1'],ascending=True).groupby('Category')

但这只会产生:<pandas.core.groupby.generic.DataFrameGroupBy object at ...>,这没什么用。

【问题讨论】:

    标签: python pandas dataframe sorting


    【解决方案1】:

    使用带有索引名称的sort_values 的一种方式:

    tmp = df.index.names
    df.index.names = ["tmp", "Category"]
    new_df = df.sort_values(["tmp", "Value1"])
    new_df.index = df.index.rename(tmp)
    print(new_df)
    

    输出:

                Value1  Value2
      Category                
    0 0             55      46
      1             62      44
      2             73      75
    1 0             34      35
      1             55      46
      2             61      49
    2 0             44      25
      1             55      46
      2             62      48
    

    【讨论】:

      【解决方案2】:

      您可以按如下方式应用它:

      import pandas as pd
      
      df = pd.DataFrame({'col1': [0, 1, 2, 0, 1, 2], 'col2': [8, 9, 6, 40, 3, 20], 'col3': [5, 6, 0, 40, 3, 20]})
      sorted_df = df.sort_values(['col2'], ascending=True)
      df[['col2', 'col3']] = sorted_df[['col2', 'col3']].values
      print(df)
      

      输出:

         col1  col2  col3
      0     0     3     3
      1     1     6     0
      2     2     8     5
      3     0     9     6
      4     1    20    20
      5     2    40    40
      

      【讨论】:

      • 我冒昧地简化了您的列分配;)(并为您的答案+1)
      【解决方案3】:

      您可以根据值和第一级索引对数据框进行排序:

      >>> df = (df.sort_values(by=['Value1', 'Value2'])
                  .sort_index(level=0, sort_remaining=False)
                )
      
                  Value1  Value2
        Category                
      0 1             55      46
        0             62      44
        2             73      75
      1 2             34      35
        1             55      46
        0             61      49
      2 2             44      25
        1             55      46
        0             62      48
      

      然后您需要使用cumcount 每组重写level1:

      df.sort_values(by=['Value1', 'Value2']).sort_index(level=0, sort_remaining=False)
      idx = pd.MultiIndex.from_arrays([df.index.get_level_values(0),
                                       pd.Series(range(len(df))).groupby(df.index.get_level_values(0)).cumcount()],
                                      names=(None, 'Category')
                                      )
      df.index = idx
      

      输出:

                  Value1  Value2
        Category                
      0 0             55      46
        1             62      44
        2             73      75
      1 0             34      35
        1             55      46
        2             61      49
      2 0             44      25
        1             55      46
        2             62      48
      

      【讨论】:

        【解决方案4】:

        一行解决方案应该是DataFrame.rename_axisDataFrame.sort_valuesDataFrame.set_index

        df = df.rename_axis(index={None:'tmp'}).sort_values(['tmp', "Value1"]).set_index(df.index)
        print (df)
                    Value1  Value2
          Category                
        0 0             55      46
          1             62      44
          2             73      75
        1 0             34      35
          1             55      46
          2             61      49
        2 0             44      25
          1             55      46
          2             62      48
        

        【讨论】:

        • 我没有按要求重置 level1 ;)
        • @mozway - 把最后一个rename_axis改成set_index解决这个问题
        猜你喜欢
        • 1970-01-01
        • 2020-12-14
        • 1970-01-01
        • 2023-03-12
        • 2022-10-12
        • 2019-01-13
        • 2020-11-11
        • 2022-11-14
        • 1970-01-01
        相关资源
        最近更新 更多