Fastest way to wrap a Numpy array

I am running some simulations that involve comparing values ​​in 2D Numpy arrays multiple times with their neighbors; eg. the value at the pointer location is (y,x)

compared with the value at the pointer location (y-1,x)

from the same array.

I am currently 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 

      

It has the ability to use either edge values ​​or zeros for comparison on the edge of the array. Functions can also do this in any direction along any axis.

Does anyone have any suggestions for a faster way to do this? I've tried np.roll

(much slower) and this:

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

      

which is slightly slower.

These functions are called ~ 200 times per second in a program that takes 10 hours, so any small speedups are more welcome!

Thank.

EDIT:

So, if the same differentiation method is required every time the shift function is called, then the Divakars method seems to offer a slight speedup, however if only the shifted array is required, then both the method and the one I am using above seem to be equal speed.

+3


source to share


1 answer


You can have offset and differentiation done in a function call, for example:

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

      

So the equivalent modified version syf

for runtime comparison purposes would be -

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 syf

with the suggested approach to runtime performance for the inputs listed in the question code -

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 are some improvements there!

+3


source







All Articles