I’m looking for a way to calculate the average absolute difference between neighboring elements in a NumPy array. Namely, given an array like
JavaScript
x
4
1
[[1, 2, 3],
2
[4, 5, 6],
3
[7, 8, 9]]
4
The value for the middle square will be 2.5 (aka (4+3+2+1+1+2+3+4)/8
). I know with SciPy’s correlate2d
you can compute the average difference, but, as far as I know, not the average absolute difference (i.e. for the example above, correlate2d
would give 0 – (-4+-3+-2+-1+1+2+3+4)/8
– not 2.5).
Is there a fast way to do this in Python? I don’t want to iterate over the elements since this will be running for very large arrays many times.
Advertisement
Answer
Why not write it by hand and numba.jit
the result?
JavaScript
1
18
18
1
arr = (np.arange(10**6)+1).reshape(10**3,10**3)
2
3
@nb.njit
4
def get_avg_abs_diff(arr):
5
n,m = arr.shape
6
out = np.empty((n,m))
7
for i in range(n):
8
for j in range(m):
9
a = max(0,i-1)
10
b = i+2
11
c = max(0,j-1)
12
d = j+2
13
neighbours = arr[a:b,c:d]
14
out[i,j] = np.sum(np.abs(neighbours-arr[i,j]))/(neighbours.shape[0]*neighbours.shape[1]-1)
15
return out
16
17
get_avg_abs_diff(arr)
18
This takes about 160ms for the 1000 by 1000 array (down from non jited version which takes 10.6s).
For your array I get
JavaScript
1
4
1
array([[2.66666667, 2.2 , 2. ],
2
[2.6 , 2.5 , 2.6 ],
3
[2. , 2.2 , 2.66666667]])
4