我有两个1D数组包含相同的值集,但是以不同的(随机)顺序。我想找到索引列表,它根据另一个重新排序一个数组。例如,我的2个数组是:
ref = numpy.array([5,3,1,2,3,4])
new = numpy.array([3,2,4,5,3,1])
我希望列表order
为new[order] == ref
。
我目前的想法是:
def find(val):
return numpy.argmin(numpy.absolute(ref-val))
order = sorted(range(new.size), key=lambda x:find(new[x]))
然而,只有在没有重复值的情况下,这才有效。在我的示例3
中出现两次,我得到new[order] = [5 3 3 1 2 4]
。第二个3
直接放在第一个val()
之后,因为我的函数3
无法跟踪我当前正在寻找的order
。
所以我可以添加一些东西来解决这个问题,但我觉得可能有更好的解决方案。也许在某些图书馆(NumPy或SciPy)?
关于副本的编辑:这个linked solution假定数组是有序的,或者对于"无序的#34;解决方案,返回重复索引。我需要每个索引在sort_idx = A.argsort(); order = sort_idx[np.searchsorted(A,B,sorter = sort_idx)]
中只出现一次。然而,哪一个首先出现并不重要(根据提供的数据也不可能)。
我使用[3, 0, 5, 1, 0, 2]
获得的是:[3, 0, 5, 1, 4, 2]
。但我要找的是.lower-part-of-element
。
答案 0 :(得分:2)
鉴于彼此改组的v_n
,E
,我们可以获取使用ref
映射到new
的唯一索引两个数组的排序版本以及invertibility的np.argsort
。
开始于:
ref
现在new
和i = np.argsort(ref)
j = np.argsort(new)
都给出了数组的排序版本,两者都是相同的。您可以通过执行以下操作来反转第一种排序:
ref[i]
现在new[j]
只是k = np.argsort(i)
或ref
。由于所有操作都使用唯一索引进行混洗,因此最终索引new[j][k]
也是唯一的。可以使用
new[j[k]]
j[k]
从原始示例:
j[k]
这可能不比similar question on SO的更一般的解决方案快,但它确实保证了您请求的唯一索引。进一步的优化是用this answer中的order = np.argsort(new)[np.argsort(np.argsort(ref))]
函数替换>>> ref = np.array([5, 3, 1, 2, 3, 4])
>>> new = np.array([3, 2, 4, 5, 3, 1])
>>> np.argsort(new)[np.argsort(np.argsort(ref))]
>>> order
array([3, 0, 5, 1, 4, 2])
>>> new[order] # Should give ref
array([5, 3, 1, 2, 3, 4])
。我会更进一步,只计算排序的倒数:
np.argsort(i)