Python 如何按频率对NumPy阵列进行排序?

Python 如何按频率对NumPy阵列进行排序?,python,arrays,sorting,numpy,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

我试图按元素的频率对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],但它不正确,因为它无法处理两个元素出现次数相同的情况

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

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])

非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]

使用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)))

如果值为整数且较小,或者您只关心大小为1的箱子:

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]

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

unique\u元素,频率=np.unique(数组,返回\u计数=True)
排序的索引=np.argsort(频率)[::-1]
按频率排序=唯一元素[已排序索引]

一旦执行
设置(arr)
,订单就会丢失。如何确保输入数组的顺序对于具有相同计数的2个值保持不变?除非选择其他排序方法,否则Python argsort是不稳定的。