如何按频率对NumPy数组排序?

时间:2018-08-08 00:56:30

标签: python arrays sorting numpy

我正在尝试按元素频率对NumPy数组排序。因此,例如,如果存在数组[3,4,5,1,2,4,1,1,2,4],则输出将是另一个NumPy,从最常见到最不常见的元素排序(没有重复项)。因此解决方案将是[4,1,2,3,5]。如果两个元素的出现次数相同,则最先出现的元素将被放置在输出中的第一位。我已经尝试过执行此操作,但是似乎无法获得实用的答案。到目前为止,这是我的代码:

temp1 = problems[j]
indexes = np.unique(temp1, return_index = True)[1]
temp2 = temp1[np.sort(indexes)]
temp3 = np.unique(temp1, return_counts = True)[1]
temp4 = np.argsort(temp3)[::-1] + 1

问题[j]是一个像[3,4,5,1,2,4,1,1,2,4]之类的NumPy数组。到目前为止,temp4返回[4,1,2,5,3],但这是不正确的,因为当两个元素具有相同的出现次数时,它无法处理。

5 个答案:

答案 0 :(得分:3)

您可以对每个元素的频率使用 argsort 来查找排序位置并将索引应用于唯一元素数组

unique_elements, frequency = np.unique(array, return_counts=True)
sorted_indexes = np.argsort(frequency)[::-1]
sorted_by_freq = unique_elements[sorted_indexes]

答案 1 :(得分:2)

非NumPy解决方案(仍可与NumPy数组一起使用)是使用OrderedCounter,然后使用sorted和自定义函数:

from collections import OrderedDict, Counter

class OrderedCounter(Counter, OrderedDict):
    pass

L = [3,4,5,1,2,4,1,1,2,4]

c = OrderedCounter(L)
keys = list(c)

res = sorted(c, key=lambda x: (-c[x], keys.index(x)))

print(res)

[4, 1, 2, 3, 5]

答案 2 :(得分:0)

您可以计算数组中每个元素的数量,然后将其用作内置sorted函数的键

def sortbyfreq(arr):
    s = set(arr)
    keys = {n: (-arr.count(n), arr.index(n)) for n in s}
    return sorted(list(s), key=lambda n: keys[n])

答案 3 :(得分:0)

使用zip和itemgetter应该有帮助

from operator import itemgetter
import numpy as np
temp1 = problems[j]
temp, idx, cnt = np.unique(temp1, return_index = True, return_counts=True)
cnt = 1 / cnt
k = sorted(zip(temp, cnt, idx), key=itemgetter(1, 2))
print(next(zip(*k)))

答案 4 :(得分:0)

如果值是整数且很小,或者您只关心大小为1的bin:

def sort_by_frequency(arr):
    return np.flip(np.argsort(np.bincount(arr))[-(np.unique(arr).size):])

v = [1,1,1,1,1,2,2,9,3,3,3,3,7,8,8]
sort_by_frequency(v)

这应该产生

array([1, 3, 8, 2, 9, 7]