最近的邻居

时间:2013-11-14 18:19:24

标签: python numpy nearest-neighbor

我正在编写一段代码来打印矩阵元素的最近邻居。我得到了

"invalid index" error

当我尝试打印邻居列表(最后一行)时。你能发现原因吗?

以下是代码:

neighbours = ndarray((ran_x-2, ran_y-2,8),int)
for i in range(0, ran_x):
    for j in range(0, ran_y):
        if 1 < i < ran_x-1:
           if 1 < j < ran_y-1:
              neighbours = ([matrix[i-1,j-1],matrix[i-1,j],matrix[i-1,j+1],matrix[i,j-1],matrix[i,j+1],matrix[i+1,j-1],matrix[i+1,j],matrix[i+1,j+1]])
neighbours = np.array(neighbours)
for l in range(1, ran_x-1):
    for m in range(1, ran_y-1):                
        print neighbours[l,m]

3 个答案:

答案 0 :(得分:1)

查看数组的大小,它是一个(ran_x - 2) * (ran_y - 2)元素数组:

neighbours = ndarray((ran_x-2, ran_y-2,8),int)

您尝试访问索引ran_x-1ran_y-1的元素,这些元素超出范围。

答案 1 :(得分:1)

滑动窗口stride_tricks非常适用于此(https://stackoverflow.com/a/11000193/541038

import numpy as np
from numpy.lib.stride_tricks import as_strided

def sliding_window(arr, window_size):
    """ Construct a sliding window view of the array"""
    arr = np.asarray(arr)
    window_size = int(window_size)
    if arr.ndim != 2:
        raise ValueError("need 2-D input")
    if not (window_size > 0):
        raise ValueError("need a positive window size")
    shape = (arr.shape[0] - window_size + 1,
             arr.shape[1] - window_size + 1,
             window_size, window_size)
    if shape[0] <= 0:
        shape = (1, shape[1], arr.shape[0], shape[3])
    if shape[1] <= 0:
        shape = (shape[0], 1, shape[2], arr.shape[1])
    strides = (arr.shape[1]*arr.itemsize, arr.itemsize,
               arr.shape[1]*arr.itemsize, arr.itemsize)
    return as_strided(arr, shape=shape, strides=strides)

def cell_neighbors(arr, i, j, d):
    """Return d-th neighbors of cell (i, j)"""
    w = sliding_window(arr, 2*d+1)

    ix = np.clip(i - d, 0, w.shape[0]-1)
    jx = np.clip(j - d, 0, w.shape[1]-1)

    i0 = max(0, i - d - ix)
    j0 = max(0, j - d - jx)
    i1 = w.shape[2] - max(0, d - i + ix)
    j1 = w.shape[3] - max(0, d - j + jx)

    return w[ix, jx][i0:i1,j0:j1].ravel()

x = np.arange(8*8).reshape(8, 8)
print x

for d in [1, 2]:
    for p in [(0,0), (0,1), (6,6), (8,8)]:
        print "-- d=%d, %r" % (d, p)
        print cell_neighbors(x, p[0], p[1], d=d)

答案 2 :(得分:0)

问题是你不断将neighbours重新分配给长度为8的1D数组。相反,你应该将邻居数据分配给你已经创建的数组的 slice

for i in range(1, ran_x-1):
    for j in range(1, ran_y-1):
        neighbours[i-1,j-1,:] = [matrix[i-1,j-1],matrix[i-1,j],matrix[i-1,j+1],matrix[i,j-1],matrix[i,j+1],matrix[i+1,j-1],matrix[i+1,j],matrix[i+1,j+1]]

请注意,我更改了范围,因此您不需要if语句。您的代码将更快,并且(可以说)更整洁如下:

neighbours = np.empty((ran_x-2, ran_y-2, 8), int)

# bool array to extract outer ring from a 3x3 array:
b = np.array([[1,1,1],[1,0,1],[1,1,1]], bool)

for i in range(ran_x-2):
    for j in range(ran_y-2):
        neighbours[i,j,:] = matrix[i:i+3, j:j+3][b]

当然,如果你需要的话,立即打印邻居而不存储它们会更快。