首页 > 解决方案 > 按另一个排序一个numpy数组

问题描述

我有一个确定元素顺序的数组:

order = [3, 1, 4, 2]

然后我想对另一个更大的数组(仅包含那些元素)进行排序:

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

这样首先出现的元素order在结果中首先出现,等等。
在直接的 Python 中,我会用一个关键函数来做到这一点:

sorted(a, key=order.index)
[3, 3, 1, 1, 1, 4, 4, 2]

我怎样才能(有效地)用 numpy 做到这一点?numpy 数组是否有类似的“键函数”概念?

标签: pythonarrayssortingnumpy

解决方案


具体案例:Ints

对于ints,我们可以使用bincount-

np.repeat(order,np.bincount(a)[order])

样品运行 -

In [146]: sorted(a, key=order.index)
Out[146]: [3, 3, 1, 1, 1, 4, 4, 2]

In [147]: np.repeat(order,np.bincount(a)[order])
Out[147]: array([3, 3, 1, 1, 1, 4, 4, 2])

通用案例

方法#1

bincount用-泛化所有 dtypes

# https://stackoverflow.com/a/41242285/ @Andras Deak
def argsort_unique(idx):
    n = idx.size
    sidx = np.empty(n,dtype=int)
    sidx[idx] = np.arange(n)
    return sidx

sidx = np.argsort(order)
c = np.bincount(np.searchsorted(order,a,sorter=sidx))
out = np.repeat(order, c[argsort_unique(sidx)])

方法#2-A

当所有元素都在np.unique时的情况下-searchsortedordera

unq, count = np.unique(a, return_counts=True)
out = np.repeat(order, count[np.searchsorted(unq, order)])

方法#2-B

为了涵盖所有情况,我们需要一个额外的步骤 -

unq, count = np.unique(a, return_counts=1)
sidx = np.searchsorted(unq, order)
out = np.repeat(order, np.where(unq[sidx] == order,count[sidx],0))

推荐阅读