Numpy 获取另一个数组中一个数组的值的索引

Numpy 获取另一个数组中一个数组的值的索引,numpy,Numpy,我有两个1D数组,它们包含相同的值集,但顺序不同(随机)。我想找到索引列表,它根据另一个数组对一个数组重新排序。例如,我的两个阵列是: 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(r

我有两个1D数组,它们包含相同的值集,但顺序不同(随机)。我想找到索引列表,它根据另一个数组对一个数组重新排序。例如,我的两个阵列是:

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

所以我可以添加一些东西来处理这个问题,但我觉得可能有更好的解决方案。也许在某个图书馆(NumPy或SciPy)

编辑关于重复:这假设数组是有序的,或者对于“无序”解决方案,返回重复的索引。我需要每个索引在
顺序中只显示一次
。但是,哪一个先到并不重要(根据提供的数据,这两种方法都不可能)


我通过
sort_idx=A.argsort()得到了什么;顺序=sort\u idx[np.searchsorted(A,B,sorter=sort\u idx)]
是:
[3,0,5,1,0,2]
。但是我要寻找的是
[3,0,5,1,4,2]
给定
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]
可通过以下步骤一次计算:

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)
替换为中的
argsort\u unique
函数。我会更进一步,只计算排序的倒数:

def inverse_argsort(a):
    fwd = np.argsort(a)
    inv = np.empty_like(fwd)
    inv[fwd] = np.arange(fwd.size)
    return inv

order = np.argsort(new)[inverse_argsort(ref)]

如果元素被重复,得到哪个索引真的很重要吗?您是否试图做一些比
a[ind]
更多的事情来获取
b
?尽管如此,是的,有一种方法可以使用多个argsorts。“我一到真正的电脑就会写出来。”迪瓦卡。这不是同一个问题。它要求找到洗牌的索引,而不是子集。因此,使用argsort可能会有一个很好的优化,它不适用于其他问题。我希望你们支持我重新开放的投标。@Madphyperator不确定你们指的是哪一个子集。那里的searchsorted解决方案给出了索引,这是本问题中预期的
顺序。你们试过那个解决方案吗?@Divakar我试过了,我得到了一些按
顺序排列的多个索引(见编辑)。这个想法似乎是正确的。为了进一步优化它,我们可以使用get
k
@Divakar。“我把它加到了答案上。”费奥多兰说。我明白你编辑的目的。我把它弄坏了,但我会更新自己的。很好,谢谢。一开始我有点担心打了三次电话
argsort
。但是
反向排序
非常好地优化了这一点,速度是原来的两倍多。@Feodoran。如果使用对
lexsort
的适当调用替换了
argsort
,则反转函数将正常工作。