对于没有for循环的等距元素的矩阵计算

时间:2012-09-18 15:45:14

标签: python matrix numpy

我有2D numpy数组和带有一些坐标(i,j)的中心(坐标意味着行和列)。我需要总结 所有与中心相同距离的阵列元素(简单 对于从0到图像边缘的每个可能距离的euklidean距离,即结果是1D阵列,其中第0个元素给出距离中心(即仅中心)距离0的像素之和,第1个元素是所有的总和距离为1像素的像素,依此类推。

我的感觉是,如果没有for循环,这应该是可行的, 但不幸的是,我不知道足够的矩阵python技巧 这个。

非常感谢!

5 个答案:

答案 0 :(得分:3)

我不确定这是否是您想要的,但它可能会有所帮助:

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])

答案 1 :(得分:2)

您可以使用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)

result是一个result[distance]的数组,它给出距离更小或相等的所有值的总和。

答案 2 :(得分:2)

我会建议一个策略,但现在没时间建议工作代码。请执行下列操作: (请注意,您不能选择精确的距离,而是连续的,连续的距离范围,因为很少的点将在精确的给定距离处。)

  1. 从阵列中创建KDTree;
  2. 获取给定圆圈内的每个点的总和,对于线性增加的圆圈;
  3. 通过从外圈减去内圈来计算每个圆圈之间“shell”的值。
  4. 它应该是这样的(当然你必须填补一些空白):

    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)
    

    希望这有帮助!

答案 3 :(得分:1)

创建一些示例点:

>>> 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])

答案 4 :(得分:1)

这对于超大型阵列来说不会很好地扩展,并且它不那么强大,但无论如何它都很可爱。

制作一个测试阵列:

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])