简体   繁体   English

移动Numpy阵列的最快方法

[英]Fastest way to shift a Numpy array

I'm running some simulations that involve repeatedly comparing values in 2D Numpy arrays with their 'neighbours'; 我正在运行一些模拟,涉及重复比较2D Numpy数组中的值与它们的“邻居”; eg. 例如。 the value at indicie location (y,x) is compared to the value at indicie location (y-1,x) from the same array. 将标记位置(y,x)处的值与来自相同阵列的标记位置(y-1,x)处的值进行比较。

At the moment I am using functions like this: 目前我正在使用这样的功能:

# example of the typical size of the arrays
my_array = np.ndarray((500,500))    

shapey, shapex = my_array.shape
Yshape = (1, shapex)
Yzeros = np.zeros((1, shapex))

def syf(A, E=True):
    if E == True:
        return np.concatenate((A[1:], A[-1].reshape(Yshape)), axis=0)
    else:
        return np.concatenate((A[1:], Yzeros), axis=0)

shifted_array = syf(my_array)

difference_in_y = shifted_array - my_array 

This has the option to use either the edge values or zeros for comparison at the edge of the array. 这可以选择在数组边缘使用边值或零进行比较。 The functions can also do it in either direction in either axis. 这些功能也可以在任一轴上的任一方向上进行。

Does anybody have any suggestions for a faster way to do this? 有没有人建议以更快的方式做到这一点? I've tried np.roll (much slower) and this: 我试过np.roll (慢得多),这个:

yf = np.ix_(range(shapey)[1:] + [shapey,], range(shapex))
shifted_array = my_array[yf]

which is a little slower. 这有点慢。

These functions are called ~200 times a second in a program that takes 10 hours to run so any small speedups are more that welcome! 这些函数在一个程序中被称为每秒200次,需要10个小时才能运行,所以任何小的加速都更受欢迎!

Thanks. 谢谢。

EDIT: 编辑:

So if the same differentiation method is required every time the shift function is called then Divakars method below seems to offer a minor speedup, however if just a shifted array is required both that method and the one I use above seem to be equal speed. 因此,如果每次调用移位函数时都需要相同的微分方法,那么下面的Divakars方法似乎提供了较小的加速,但是如果只需要一个移位的数组,则该方法和我上面使用的方法似乎是相等的速度。

You could have the shifting and differentiating both done in a function call like so - 您可以在函数调用中完成移位和区分,如此 -

def syf1(A, E=True):
    out = np.empty_like(A)
    out[:-1] = A[1:] - A[:-1] # Or np.diff(my_array,axis=0)
    if E == True:
        out[-1] = 0
    else:
        out[-1] = -A[-1]
    return out

Thus, the equivalent modified version of syf for runtime comparison purposes would be - 因此,用于运行时比较目的的syf的等效修改版本将是 -

def syf(A, E=True):
    if E == True:
        return np.concatenate((A[1:], A[-1].reshape(Yshape)), axis=0) - A
    else:
        return np.concatenate((A[1:], Yzeros), axis=0) - A

Runtime tests 运行时测试

Let's compare the equivalent version of syf with the proposed approach on runtime performance for the inputs listed in the question code - 让我们将syf的等效版本与问题代码中列出的输入的运行时性能建议方法进行比较 -

In [113]: %timeit syf(my_array)
1000 loops, best of 3: 518 µs per loop

In [114]: %timeit syf1(my_array)
1000 loops, best of 3: 494 µs per loop

So, there is some improvement there! 那么,那里有一些改进!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM