按频率和Python中的值对列表进行排序

问题描述 投票:1回答:2

我有一个数字列表说,[2,2,3,3,4,1]我想按频率排序,如果频率计数(升序)相同,则按值排序(也按升序排序)。索恩将是[1,4,2,2,3,3]

对于频率

from collections import Counter
print sorted(arr, key=Counter(arr).get)

但我不确定如何按相同频率计数元素的值排序

python list sorting
2个回答
3
投票

跟进@ bro-grammer的评论(我使用了元组的密钥,只调用了一次Counter):

有这种方法首先必须通过列表进行计数,然后再进行一些排序。

from collections import Counter
def perseus_sort(l):
    counter = Counter(l)
    return sorted(l, key=lambda x: (counter[x], x))

可能有一些聪明的算法可以以某种方式结合这两者,但我的直觉是它会非常复杂并且超出你的需要


2
投票

这是通过numpy.uniquenumpy.lexsort的一种方式:

import numpy as np

arr = np.array([2,2,3,3,4,1])

c = dict(zip(*np.unique(arr, return_counts=True)))

res = arr[np.lexsort((arr, list(map(c.get, arr))))]

# array([1, 4, 2, 2, 3, 3])

以下针对大型阵列的一些基准测试:

from collections import Counter
import numpy as np

arr = np.random.randint(0, 9, 100000)

def jp(arr):
    c = dict(zip(*np.unique(arr, return_counts=True)))
    res = arr[np.lexsort((arr, list(map(c.get, arr))))]
    return res

def perseus_sort(l):
    counter = Counter(l)
    return sorted(l, key=lambda x: (counter[x], x))

%timeit jp(arr)            # 39.2 ms
%timeit perseus_sort(arr)  # 118 ms
© www.soinside.com 2019 - 2024. All rights reserved.