使用索引数组进行高效循环

sta*_*ane 1 python indexing for-loop numpy

如果我有一个包含所有唯一顺序值的索引数组,例如:

index_array = array([0, 4, 2, 5, 6, 1, 3, 7, 8])
Run Code Online (Sandbox Code Playgroud)

使用相应的值数组:

value_array = array([0, 400, 200, 500 600, 100, 300, 700, 800])
Run Code Online (Sandbox Code Playgroud)

是否有可能按顺序循环索引数组,这样我就可以了

array([0, 100, 200, 300, 400, 500, 600, 700, 800])
Run Code Online (Sandbox Code Playgroud)

我需要按顺序循环索引数组(即0,1,2,3,4 ......)和相应的值(即0,100,200,300,400).这些值不按顺序的原因是因为我细分了边,这意味着新的边被添加到索引数组的末尾(使用vstack),而不是在适当的点插入到索引数组中.

伪代码(如果我打印出值),将是这样的:

for point in sorted(index_array):

    print sorted(point(value_array))
Run Code Online (Sandbox Code Playgroud)

生产:

0

100

200

300
Run Code Online (Sandbox Code Playgroud)

这对内存是多么敏感(我猜我需要使用numpy.where)在循环之前重新排序是不是更好的做法,还是循环乱序的性能成本?

Div*_*kar 5

方法#1

获取索引数组的argsort和索引值数组 -

value_array[index_array.argsort()]
Run Code Online (Sandbox Code Playgroud)

样品运行 -

In [129]: value_array
Out[129]: array([   0,  400,  200,  500,  600,  100,  300,  700, 800])

In [130]: index_array
Out[130]: array([0, 4, 2, 5, 6, 1, 3, 7, 8])

In [131]: value_array[index_array.argsort()]
Out[131]: array([   0,  100,  200,  300,  400,  500,  600,  700, 800])
Run Code Online (Sandbox Code Playgroud)

方法#2滥用所有元素index_array都是唯一和顺序的事实,更快的方法是初始化输出数组并使用这些索引来索引并将这些值分配value_array到其中,如下所示 -

def assign_unique_seq(value_array, index_array):
    out = np.empty_like(value_array)
    out[index_array] = value_array
    return out
Run Code Online (Sandbox Code Playgroud)

运行时测试 -

In [152]: value_array = np.random.randint(0,1000000,(100000))

# Create unique and sequential indices array
In [153]: index_array = np.random.permutation(len(value_array))

In [154]: %timeit value_array[index_array.argsort()]
100 loops, best of 3: 7.84 ms per loop

In [155]: %timeit assign_unique_seq(value_array, index_array)
1000 loops, best of 3: 240 µs per loop
Run Code Online (Sandbox Code Playgroud)