I have 2D numpy arrays and a center with some coordinates (i, j) (coordinates mean row and column). I need to sum up all array elements at the same distance from the center (simple euklidean distance) for each possible distance from 0 to the edge of the image, i.e. result is an 1D array where the 0th element gives the sum of pixels in distance 0 from center (i.e. just the center), 1st element is the sum of all pixels at distance 1 pixel and so on.
My feeling is that this should be possible to do without a for loop, but unfortunately I don't know enough matrix python tricks to figure this out.
Thank you very much!
I'm not sure if this is what you want, but it may be helpful:
import numpy as np
#create data arrays to work with.
x = np.arange(10)
y = np.arange(10)
v = np.arange(100).reshape(10,10)
#indices of the "center" of the grid
i,j = 5,5
#Now calculated the distance of each point to the center point on the grid
#Note that `None` is the same as `np.newaxis`
r = np.sqrt((x[:,None] - x[i])**2 + (y[None,:]-y[j])**2)
#Now sum all the points that are closer than 10 units away.
np.sum(v[r<=10])
You can use np.bincount
...
a = np.random.random((20, 22))
def distance(array, xpos, ypos):
# probably a gazillion methods to create the actual distances...
# if you array is large and you are only interested to a certain size
# you sould probably slice out a smaller one first of course.
dists = np.sqrt(np.arange(-xpos, array.shape [0]-xpos, dtype=float)[:,None]**2
+ np.arange(-ypos, array.shape [1]-ypos, dtype=float)[None,:]**2)
return dists
# Prepare which bins to use:
dists = distance(a, 10, 11).astype(int)
# Do a bincount with weights.
result = np.bincount(dists.flat, weights=a.flat)
# and add them up:
result = np.add.accumulate(result)
And result
is an array with result[distance]
giving sum over all values with smaller or equal distances.
I'll suggest a strategy, but have no time now to suggest working code. Do the following: (note that you cannot chose an exact distance, but consecutive, continuous RANGES of distances, since very few points will be at a precise given distance).
It should be something like this (of course you'll have to fill some blanks):
import numpy
from scipy.spatial import KDTree
tree = scipy.spatial.KDTree(reshaped_array)
sums = [numpy.sum(tree.query_ball_point(dist)) for dist in xrange(desired_distances)]
desired_result = numpy.diff(sums)
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With