python - 按另一个排序一个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 数组是否有类似的“键函数”概念?
解决方案
具体案例: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
时的情况下-searchsorted
order
a
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))
推荐阅读
- android - 在覆盖函数中调用被覆盖的函数
- angular - 显示不推荐使用get方法的输出如何解决?
- python - 如何注册 Django 管理员批准?
- python - 在 Docker 上安装 detectron2 包
- scala - 验证集合中的元素,为第一个无效元素返回失败
- classification - makeClassifTask 中的错误 - 要加入的列必须指定“on=”
- php - 显示实时日期
- android - 从存储访问框架 (SAF) 收到的带有 Uri 的 Android contentResolver.query
- javascript - 使用内容创建的产品图像未显示
- url-rewriting - 如何在 Yii2 中开始使用 Slug URL 而不会破坏旧版本