Reputation: 33243
I have a numpy matrix I mXn...
Now, I want to perform the following operation:
J(x, y) = I(x+1, y) - I(x, y)
The difference operator is "absolute" difference (ie no negative value in matrix J)
Now, I have a lame way to do this which involves looping but want to avoid that here?
Edit: The J(x,y) is of size m X (n-1)
Upvotes: 2
Views: 1613
Reputation: 805
Maybe something like this?
import numpy as np
I = np.random.randint(0, 10, (4, 6) )
J = np.abs( np.roll(I,-1, axis=0) - I )
Edit:
The solution above is assuming periodic boundaries in x. You can drop the last row by using
J = np.abs( np.roll(I,-1, axis=0) - I )[:-1, :]
instead.
Upvotes: 1
Reputation: 309929
Seems like you could use np.diff
for this along with abs
:
>>> mat
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1]])
>>> abs(np.diff(mat, axis=0))
array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
I'm not sure that there is any real advantage here over the slicing solution posted earlier -- Just when I think about taking element - to - element differences in a numpy array, I naturally think of np.diff
. . .
EDIT
It looks like the slicing solution is significantly faster:
>>> timeit.timeit('abs(np.diff(mat, axis=0))', 'from __main__ import np, mat')
3.239274024963379
>>> timeit.timeit('abs(mat[1:,:] - mat[:-1,:])', 'from __main__ import np, mat')
1.287804126739502
Looking at the code, it appears that numpy is just constructing those slices under the hood and doing the subtraction in the same way. For larger arrays (where the subtraction time starts to become comparable to the slice computation, these timings would get closer together), but np.diff
will always be slower.
Upvotes: 1
Reputation: 2662
How about with slicing like this?
# row 1 is all zeros, row 2 is all 1, row 3 all 0s ...
# 10 x 5 matrix
mat = np.array( [ [j%2 for k in range(5)] for j in range(10)])
diff = np.abs(mat[1:,:] - mat[:-1,:])
print diff.shape # 9 x 5
print diff #all ones (no negative one values)
Upvotes: 2