简体   繁体   English

groupby pandas python的自定义排序顺序功能

[英]Custom sort order function for groupby pandas python

Let's say I have a grouped dataframe like the below (which was obtained through an initial df.groupby(df["A"]).apply(some_func) where some_func returns a dataframe itself). 假设我有一个如下所示的分组数据帧(通过初始df.groupby(df["A"]).apply(some_func)其中some_func返回数据帧本身)。 The second column is the second level of the multiindex which was created by the groupby . 第二列是在第二级multiindex ,其通过所创建的groupby

A   B C
1 0 1 8
  1 3 3
2 0 1 2
  1 2 2
3 0 1 3
  1 2 4

And I would like to order on the result of a custom function that I apply to the groups. 我想订购我应用于组的自定义函数的结果。

Let's assume for this example that the function is 让我们假设这个例子是函数

def my_func(group):
    return sum(group["B"]*group["C"])

I would then like the result of the sort operation to return 然后我想要返回排序操作的结果

A   B C
2 0 1 2
  1 2 2
3 0 1 3
  1 2 4
1 0 1 8
  1 3 3

IIUC reindex after apply your function then ,do with argsort IIUC reindex后再apply你的函数,用argsort

idx=df.groupby('A').apply(my_func).reindex(df.index.get_level_values(0))
df.iloc[idx.argsort()]
Out[268]: 
     B  C
A       
2 0  1  2
  1  2  2
3 0  1  3
  1  2  4
1 0  1  8
  1  3  3

This is based on @Wen-Ben's excellent answer, but uses sort_values to maintain the intra/inter group orders. 这是基于@ Wen-Ben的优秀答案,但使用sort_values来维护组内/组间订单。

df['func'] = (groups.apply(my_func)
              .reindex(df.index.get_level_values(0))
              .values)

(df.reset_index()
 .sort_values(['func','A','i'])
 .drop('func', axis=1)
 .set_index(['A','i']))

Note : the default algorithm for idx.argsort() , quicksort , is not stable. 注意 :默认算法idx.argsort() quicksort ,是不是稳定。 That's why @Wen-Ben's answer fails for complicated datasets. 这就是@ Wen-Ben的答案因复杂的数据集而失败的原因。 You can use idx.argsort(kind='mergesort') for a stable sort, ie, maintaining the original order in case of tie values. 您可以使用idx.argsort(kind='mergesort')进行稳定排序,即在绑定值的情况下保持原始顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM