質問

I am writing a piece of code to print the nearest neighbors for the elements of a matrix. I get an

"invalid index" error

when I try to print the list of the neighbours (last line). Can you spot why?

Here's the code:

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

The problem is you continuously reassign neighbours to a 1D array with length 8. Instead you should assign the neighbour data to a slice of the array you had already created:

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

Note that I changed the ranges so you don't need the if statements. Your code would be faster and (arguably) neater as the following:

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]

Of course it would be faster still to immediately print the neighbours without storing them at all, if that's all you need.

他のヒント

Look at the size of your array, it's a (ran_x - 2) * (ran_y - 2) elements array:

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

And you try to access the elements at index ran_x-1 and ran_y-1 which are out of bound.

sliding window stride_tricks is great for this (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)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top