我有两个整数numpy数组,比如,arr1
和arr2
,它们是range(some_length)
我想得到第三个,其中
所有arr3[idx] = arr1.get_index_of(arr2[idx])
的 idx = 0,1,2,..., some_length-1
这里get_index_of method
是获取集合中某个元素的索引的伪方法。
这可以通过对所有的indeces进行天真循环来完成,搜索对应的元素,然后分配它的索引等等。
但这很慢 - O(n ^ 2)。可以更快地完成(至少n * log(n)复杂度)?可以通过漂亮的numpy方法完成吗?也许用一些非平凡的key=
参数进行排序?当然有一些优雅的解决方案。
提前谢谢。
答案 0 :(得分:2)
说,a
是0..9
的排列:
>>> a = np.random.permutation(10)
>>> a
array([3, 7, 1, 8, 2, 4, 6, 0, 9, 5])
然后,索引器数组是:
>>> i = np.empty(len(a), dtype='i8')
>>> i[a] = np.arange(len(a))
>>> i
array([7, 2, 4, 0, 5, 9, 6, 1, 3, 8])
这意味着,0
中的a
索引为i[0] == 7
,自a[7] == 0
起为真。
因此,在您的示例中,假设您有一个额外的向量b
,您可以执行以下操作:
>>> b
array([5, 9, 4, 8, 6, 1, 7, 2, 3, 0])
>>> i[b]
array([9, 8, 5, 3, 6, 2, 1, 4, 0, 7])
这意味着,b[0] == 5
5
和a
中的i[b][0] == 9
索引为a[9] = 5 = b[0]
,这是真的,因为{{1}}。
答案 1 :(得分:1)
让我们试一下测试用例
In [166]: arr1=np.random.permutation(10)
In [167]: arr2=np.random.permutation(10)
In [168]: arr1
Out[168]: array([4, 3, 2, 9, 7, 8, 5, 1, 6, 0])
In [169]: arr2
Out[169]: array([9, 2, 6, 4, 0, 3, 1, 7, 8, 5])
np.where(arr1==i)
会执行您的get_index_of method
,因此您的迭代解决方案是:
In [170]: np.array([np.where(arr1==i)[0] for i in arr2]).flatten()
Out[170]: array([3, 2, 8, 0, 9, 1, 7, 4, 5, 6], dtype=int32)
矢量化方法是在2个数组之间进行“outter”比较。这会生成一个(10,10)
数组,我们可以应用where
来获取索引。仍然是O(n ^ 2)方法,但它主要是编译的。在这个问题的大小上,它快5倍。
In [171]: np.where(arr1==arr2[:,None])
Out[171]:
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32),
array([3, 2, 8, 0, 9, 1, 7, 4, 5, 6], dtype=int32))