我有 2D numpy 数组和一个带有一些坐标 (i, j) 的中心(坐标表示行和列)。对于从 0 到图像边缘的每个可能距离,我需要对距中心相同距离(简单欧式距离)的所有数组元素求和,即结果是一维数组,其中第 0 个元素给出距离中的像素总和0 从中心(即只是中心),第一个元素是距离 1 像素处的所有像素的总和,依此类推。
我的感觉是,这应该可以在没有 for 循环的情况下完成,但不幸的是我不知道足够的矩阵 python 技巧来解决这个问题。
非常感谢你!
我不确定这是否是您想要的,但它可能会有所帮助:
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])
你可以使用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)
Andresult
是一个数组,result[distance]
对所有距离更小或相等的值求和。
我会建议一个策略,但现在没有时间建议工作代码。执行以下操作:(请注意,您不能选择精确的距离,而是选择连续的、连续的距离范围,因为很少有点会处于精确的给定距离)。
它应该是这样的(当然你必须填写一些空白):
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)
希望这可以帮助!
创建一些样本点:
>>> import numpy as np
>>> vals = np.array([[1,2],[3,4.5],[5,6]])
>>> vals
array([[ 1. , 2. ],
[ 3. , 4.5],
[ 5. , 6. ]])
计算中心点:
>>> center = np.mean(vals, axis=0)
>>> center
array([ 3. , 4.16666667])
计算距中心点的距离:
>>> d = vals - center
>>> dist_from_center = np.sqrt(d[:,0]*d[:,0] + d[:,1]*d[:,1])
>>> dist_from_center
array([ 2.94863434, 0.33333333, 2.71313677])
这不会很好地扩展到超大型阵列,而且它不是那么强大,但无论如何它有点可爱。
制作一个测试数组:
In [148]: import numpy as np
In [149]: m = np.random.random((8, 9))
In [150]: m
Out[150]:
array([[ 0.36254361, 0.92449435, 0.36954906, 0.13007562, 0.95031795,
0.1341706 , 0.6417435 , 0.25467616, 0.72431605],
[ 0.75959927, 0.53992222, 0.76544104, 0.94409118, 0.27048638,
0.44747388, 0.42691671, 0.75695594, 0.10366086],
[ 0.12424304, 0.06642197, 0.08953764, 0.66546555, 0.30932551,
0.50375697, 0.1344662 , 0.31008366, 0.13953257],
[ 0.28643294, 0.12986936, 0.39022482, 0.72869735, 0.84537494,
0.62683481, 0.88539889, 0.35697751, 0.96332492],
[ 0.67678959, 0.60373389, 0.15151052, 0.53586538, 0.50470088,
0.39664842, 0.93584004, 0.97386657, 0.50405521],
[ 0.04613492, 0.53676995, 0.60119919, 0.5559467 , 0.09392262,
0.69938864, 0.35719754, 0.79775878, 0.16634076],
[ 0.00879703, 0.60874483, 0.25390384, 0.48368248, 0.52770161,
0.64563258, 0.27353424, 0.86046696, 0.04489414],
[ 0.80883157, 0.44484305, 0.52325907, 0.49172028, 0.46731106,
0.06400542, 0.75671515, 0.55930335, 0.70721442]])
获取索引:
In [151]: centre = (3,5)
In [152]: ii = np.indices(m.shape)
In [153]: ii
Out[153]:
array([[[0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5, 5, 5, 5],
[6, 6, 6, 6, 6, 6, 6, 6, 6],
[7, 7, 7, 7, 7, 7, 7, 7, 7]],
[[0, 1, 2, 3, 4, 5, 6, 7, 8],
[0, 1, 2, 3, 4, 5, 6, 7, 8],
[0, 1, 2, 3, 4, 5, 6, 7, 8],
[0, 1, 2, 3, 4, 5, 6, 7, 8],
[0, 1, 2, 3, 4, 5, 6, 7, 8],
[0, 1, 2, 3, 4, 5, 6, 7, 8],
[0, 1, 2, 3, 4, 5, 6, 7, 8],
[0, 1, 2, 3, 4, 5, 6, 7, 8]]])
In [154]: di = ii[0]-centre[0], ii[1]-centre[1]
获取平方距离:
In [155]: dr2 = (di[0]**2+di[1]**2)
In [156]: dr2
Out[156]:
array([[34, 25, 18, 13, 10, 9, 10, 13, 18],
[29, 20, 13, 8, 5, 4, 5, 8, 13],
[26, 17, 10, 5, 2, 1, 2, 5, 10],
[25, 16, 9, 4, 1, 0, 1, 4, 9],
[26, 17, 10, 5, 2, 1, 2, 5, 10],
[29, 20, 13, 8, 5, 4, 5, 8, 13],
[34, 25, 18, 13, 10, 9, 10, 13, 18],
[41, 32, 25, 20, 17, 16, 17, 20, 25]])
并用于bincount
获得总和:
In [158]: np.bincount(dr2.flat, m.flat)
Out[158]:
array([ 0.62683481, 2.63117922, 1.88433263, 0. , 2.23253738,
3.63380441, 0. , 0. , 3.05475259, 2.13335292,
3.27793323, 0. , 0. , 3.36554308, 0. ,
0. , 0.19387479, 1.89418207, 1.3926631 , 0. ,
2.12771579, 0. , 0. , 0. , 0. ,
3.05014562, 0.80103263, 0. , 0. , 0.8057342 ,
0. , 0. , 0.44484305, 0. , 0.37134064,
0. , 0. , 0. , 0. , 0. ,
0. , 0.80883157])