Python Numpy Array geht значения соседей - PullRequest
1 голос
/ 12 мая 2019

Я хочу получить все соседние значения np.array.

Массив выглядит так:

x = np.array([  [1, 2, 3, 4 ],
                [5, 6, 7, 8],
                [9, 10, 11, 12],
                [13, 14, 15, 16] ])

Что у меня есть:

i = 2
j = 2

n = x[i,j-1], x[i,j], x[i,j+1], x[i-1,j], x[i+1,j], x[i-1,j-1], x[i+1,j+1], x[i+1,j-1], x[i-1,j+1]

Это возвращает (что я хочу)

(10, 11, 12, 7, 15, 6, 16, 14, 8)

Но также есть ошибки, например, когда я хочу значения соседей

i = 3
j = 3

Это дает:

Exception has occurred: IndexError
index 4 is out of bounds for axis 1 with size 4

Другая душа:

def find_neighbors(m, i, j, dist=1):
    return [row[max(0, j-dist):j+dist+1] for row in m[max(0,-1):i+dist+1]]

и

n = find_neighbors(x, i, j)

Что дает мне массив соседей, но также дает мне не все соседки, когда я устанавливаю

i = 0
j = 0

потому что это только дает мне:

[array([1, 2]), array([5, 6])]

У кого-нибудь есть решение для этого?

Спасибо!

Ответы [ 3 ]

1 голос
/ 12 мая 2019

Вы можете воспользоваться возможностью индексации Python для отрицательных индексов.

def wrap_nb(x,i,j):
    return x[np.ix_(*((z-1, z, z+1-S) for z,S in zip((i,j), x.shape)))].ravel()

Для этого требуется, чтобы i и j были неотрицательными и меньше, чем форма x.

Если это не гарантируется:

def wrap_nb(x,i,j):
    return x[np.ix_(*(np.r_[z-1:z+2]%S for z,S in zip((i,j), x.shape)))].ravel()

Примеры:

>>> wrap_nb(x,1,-2)
array([ 2,  3,  4,  6,  7,  8, 10, 11, 12])
>>> wrap_nb(x,0,-1)
array([15, 16, 13,  3,  4,  1,  7,  8,  5])
>>> wrap_nb(x,0,0)
array([16, 13, 14,  4,  1,  2,  8,  5,  6])
1 голос
/ 12 мая 2019
# function to find the start row and column
def find_start(x):
    start = x-1 if x-1 >= 0 else 0
    return start

# function to find the end row and column
def find_end(x, shape):
    end = x+1 if x+1 <= shape else shape
    return end

def find_neighbors(a, i, j):
    neighbors = []
    row_start, row_end = find_start(i), find_end(i, a.shape[0])
    col_start, col_end = find_start(j), find_end(j, a.shape[1])

    for y in range(a.shape[0]):
        for z in range(a.shape[1]):
            if y >= row_start and y <= row_end:
                if z >= col_start and z <= col_end:
                    neighbors.append(a[y][z])
    return neighbors

i, j = 0, 0                    
neighbors = find_neighbors(a, i, j)
print(neighbors)

Выход: [1, 2, 5, 6]

i, j = 3, 3                    
neighbors = find_neighbors(a, i, j)
neighbors

Выход: [11, 12, 15, 16]

i, j = 2, 2                    
neighbors = find_neighbors(a, i, j)
neighbors

Выход: [6, 7, 8, 10, 11, 12, 14, 15, 16]

Это будет охватывать всекрайние случаи.

0 голосов
/ 12 мая 2019

Я получил следующее решение от помощника:

Новый массив:

homes = np.array([  [1, 2, 3, 4 ],
                [5, 6, 7, 8],
                [9, 10, 11, 12],
                [13, 14, 15, 16] ])

Код для возврата соседних значений:

neighbour  = []                                          
neighbour  += [homes[i][j]]                              # value itself
neighbour   += [homes[i][(j + 1) % n]]                   # value right 
neighbour  += [homes[i][(j - 1) % n]]                    # value left
neighbour  += [homes[(i + 1) % n][j]]                    # value down
neighbour  += [homes[(i + 1) % n][(j + 1) % n]]          # value right down
neighbour  += [homes[(i + 1) % n][(j - 1) % n]]          # value left down 
neighbour  += [homes[(i - 1) % n][j]]                    # vlaue up
neighbour  += [homes[(i - 1) % n][(j + 1) % n]]          # vlaue right up
neighbour  += [homes[(i - 1) % n][(j - 1) % n]]          # value left up 

Что возвращает мне:

i = 0
j = 0

[16, 13, 15, 4, 1, 3, 12, 9, 11]

Это то, что мне нужно, но я все еще заинтересован в решении, подобном тому, что было у Абдура

...