【发布时间】:2016-02-15 10:28:58
【问题描述】:
我有以下数据集:
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 排序,以产生这个:
我已经梳理了文档,找不到直接的方法。我能做的最好的就是以下黑客:
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 选项中受益,只是这样做是为了使中间产品清晰)。
我确实找到了this SO post,它使用了分组和排序功能。但是,改编自该帖子的以下代码产生了错误的结果:
df2.groupby("fac1",axis=1).apply(lambda x : x.sort_values("val"))
(出于空间考虑,已删除输出)
还有其他方法可以解决这个问题吗?
更新:解决方案
公认的解决方案是:
df2.sort_values(by='val').sort_index(kind='mergesort')
排序算法必须是mergesort,并且必须明确指定,因为它不是默认值。正如the sort_index documentation 指出的那样,“合并排序是唯一的stable 算法。”这是另一个示例数据集,如果您不为 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