簡體   English   中英

在保留原始行的同時對數據框組進行排序

[英]Sort the Dataframe groups while retaining original rows

這是原始數據框:

Name Version Cost
A    0.0.3   1.7
C    0.0.2   2.5
A    0.0.1   1.0
C    0.0.1   2.4
B    0.0.2   3.7
B    0.0.1   3.5
A    0.0.2   1.4
C    0.0.3   2.6
B    0.0.3   3.8

使用以下代碼在組內進行分組和排序后:

df = df.sort_values(['Name', 'Version'], ascending=[True, False])
df = df.groupby(['Name'], sort=False)
df = df.apply(lambda x: x.sort_values(['Cost'], ascending=False))

現在我有了這個數據框,其中成本在組內排序,並按字母順序排列。

     Name Version Cost
Name
A    A    0.0.3   1.7
     A    0.0.2   1.4
     A    0.0.1   1.0
B    B    0.0.3   3.8
     B    0.0.2   3.7
     B    0.0.1   3.5
C    C    0.0.3   2.6
     C    0.0.2   2.5
     C    0.0.1   2.4

問題是,現在我想按每個組的總成本對組進行排序,因此預期的結果如下所示:

Name Version Cost
B    0.0.3   3.8
B    0.0.2   3.7
B    0.0.1   3.5
C    0.0.3   2.6
C    0.0.2   2.5
C    0.0.1   2.4
A    0.0.3   1.7
A    0.0.2   1.4
A    0.0.1   1.0

我怎樣才能在不丟失行的情況下實現它。

您可以創建臨時列並按它排序。 然后刪除該列:

df["tmp"] = df.groupby("Name")["Cost"].transform("sum")
df = df.sort_values(by="tmp", ascending=False).drop("tmp", 1)
print(df)

印刷:

  Name Version  Cost
3    B   0.0.3   3.8
4    B   0.0.2   3.7
5    B   0.0.1   3.5
6    C   0.0.3   2.6
7    C   0.0.2   2.5
8    C   0.0.1   2.4
0    A   0.0.3   1.7
1    A   0.0.2   1.4
2    A   0.0.1   1.0

df使用:

Name Version Cost
A    0.0.3   1.7
A    0.0.2   1.4
A    0.0.1   1.0
B    0.0.3   3.8
B    0.0.2   3.7
B    0.0.1   3.5
C    0.0.3   2.6
C    0.0.2   2.5
C    0.0.1   2.4

從您的原始數據幀開始,您可以生成一個組總和的輔助列,並根據該列進行transform和排序,以及按降序排列的Version列:

group_sums = df.groupby("Name").Cost.transform("sum")
out = (df.assign(sorter=group_sums)
         .sort_values(["sorter", "Version"], ascending=False, ignore_index=True)
         .drop(columns="sorter"))

我們在排序后刪除輔助列sorter

要得到

>>> out

  Name Version  Cost
0    B   0.0.3   3.8
1    B   0.0.2   3.7
2    B   0.0.1   3.5
3    C   0.0.3   2.6
4    C   0.0.2   2.5
5    C   0.0.1   2.4
6    A   0.0.3   1.7
7    A   0.0.2   1.4
8    A   0.0.1   1.0

您可以使用sort_valueskey參數來獲得與其他答案相同的結果:

print (df.sort_values("Cost", ascending=False,
                      key=lambda _: df.groupby("Name")["Cost"].transform("sum")))

  Name Version  Cost
3    B   0.0.3   3.8
4    B   0.0.2   3.7
5    B   0.0.1   3.5
6    C   0.0.3   2.6
7    C   0.0.2   2.5
8    C   0.0.1   2.4
0    A   0.0.3   1.7
1    A   0.0.2   1.4
2    A   0.0.1   1.0

嘗試:

df.assign(groupsum=df.groupby(level=0)['Cost'].transform('sum'))\
  .sort_values(['groupsum', 'Version'], ascending=False)

輸出:

       Name Version  Cost  groupsum
Name                               
B    8    B   0.0.3   3.8      11.0
     4    B   0.0.2   3.7      11.0
     5    B   0.0.1   3.5      11.0
C    7    C   0.0.3   2.6       7.5
     1    C   0.0.2   2.5       7.5
     3    C   0.0.1   2.4       7.5
A    0    A   0.0.3   1.7       4.1
     6    A   0.0.2   1.4       4.1
     2    A   0.0.1   1.0       4.1

並且,您可以在reset_index(drop=True)添加reset_index(drop=True)

  Name Version  Cost  groupsum
0    B   0.0.3   3.8      11.0
1    B   0.0.2   3.7      11.0
2    B   0.0.1   3.5      11.0
3    C   0.0.3   2.6       7.5
4    C   0.0.2   2.5       7.5
5    C   0.0.1   2.4       7.5
6    A   0.0.3   1.7       4.1
7    A   0.0.2   1.4       4.1
8    A   0.0.1   1.0       4.1

或者,使用上面的“原始”數據框:

df.assign(groupsum=df.groupby('Name')['Cost'].transform('sum'))\
  .sort_values(['groupsum', 'Version'], ascending=[False,False])

輸出:

  Name Version  Cost  groupsum
8    B   0.0.3   3.8      11.0
4    B   0.0.2   3.7      11.0
5    B   0.0.1   3.5      11.0
7    C   0.0.3   2.6       7.5
1    C   0.0.2   2.5       7.5
3    C   0.0.1   2.4       7.5
0    A   0.0.3   1.7       4.1
6    A   0.0.2   1.4       4.1
2    A   0.0.1   1.0       4.1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM