我有以下数据集:
import numpy as np
from pandas import DataFrame
import numpy.random as random
random.seed(12)
df = DataFrame (
{
"fac1" : ["a","a","a","a","b","b","b","b"] ,
"val" : random.choice(np.arange(0,20), 8, replace=False)
}
)
df2 = df.set_index(["fac1"])
df2
我希望的是在每个 fac1
组内按 val
进行排序,得到如下结果:
我已经仔细查阅了文档,但没有找到一个简单明了的方法。我能做到的最好办法是以下这种hack:
df3 = df2.reset_index()
df4 = df3.sort_values(["fac1","val"],ascending=[True,True],axis=0)
df5 = df4.set_index(["fac1"])
df5
# Produces the picture above
我意识到上述内容可以从多个inplace选项中受益,只是为了让中间产品清晰明了而这样做。
我找到了这篇SO帖子,它使用分组和排序函数。然而,从那篇帖子改编的以下代码产生了错误的结果。
df2.groupby("fac1",axis=1).apply(lambda x : x.sort_values("val"))
由于空间限制,输出已删除。
还有其他方法可以解决这个问题吗?
更新:解决方案
被接受的解决方案是:
df2.sort_values(by='val').sort_index(kind='mergesort')
排序算法必须为mergesort
,并且必须显式指定,因为它不是默认值。正如sort_index
文档中指出的那样,“mergesort是唯一的稳定算法。”如果您不为kind
指定mergesort
,则以下是另一个无法正确排序的示例数据集:
random.seed(12)
len = 32
df = DataFrame (
{
"fac1" : ["a" for i in range(int(len/2))] + ["b" for i in range(int(len/2))] ,
"val" : random.choice(np.arange(0,100), len, replace=False)
}
)
df2 = df.set_index(["fac1"])
df2.sort_values(by='val').sort_index()
(由于空间原因,我省略了所有输出)
len
有关 - 对于代码中的其他所有内容,提议的解决方案适用于 len <= 16,但对于更大的值则失败。 - Silenced Temporarily