python - Pandas 按值排序,然后按索引排序

标签 python pandas

我有以下数据集:

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

enter image description here

我想要的是在每个 fac1 组中按 val 排序,以产生这个:

enter image description here

我已经梳理了文档,找不到直接的方法。我能做的最好的就是以下 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 选项中获益,只是这样做是为了使中间产品清晰)。

我确实找到了 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指出,“mergesort 是唯一的 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()

(出于空间考虑,我省略了所有输出)

最佳答案

编辑:我查看了文档,发现 sort_index 的默认排序算法是快速排序。这不是一个“稳定”算法,因为它不保留“排序输出中相等元素的输入顺序”(来自维基百科)。但是,sort_index 为您提供了选择“mergesort”的选项,这是一种稳定的排序算法。所以我原来的回答,

df2.sort_values(by='val').sort_index()

,有效,只是偶然。这段代码应该每次都有效,因为它使用了稳定的排序算法:

df2.sort_values(by='val').sort_index(kind = 'mergesort')

关于python - Pandas 按值排序,然后按索引排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33699555/

相关文章:

python - 如何从给定的一组单词中打印出最长和最短的单词?

python - 如何在 Linux 和 Windows 上调用 Python 3 脚本作为 CCS/Eclipse 构建步骤?

python - Pandas 求和多个数据框

python - 切片 groupby.describe 数据框

javascript - 如何提取 d3 图表的名义标签

python - Django 。从 HDD 检索并打开 zip 文件

python - 安装 gunicorn 的语法错误

python - 如何使用Docker Compose管理Flask中的迁移?

python - 基于新数据框构建数据框

python - Pandas 面板数据 - 考虑年份差距将值移动两次