Как найти форму массива в большем массиве? - PullRequest
0 голосов
/ 30 ноября 2018
big_array = np.array((
  [0,1,0,0,1,0,0,1],
  [0,1,0,0,0,0,0,0],
  [0,1,0,0,1,0,0,0], 
  [0,0,0,0,1,0,0,0],
  [1,0,0,0,1,0,0,0]))

print(big_array)
[[0 1 0 0 1 0 0 1]
 [0 1 0 0 0 0 0 0]
 [0 1 0 0 1 0 0 0]
 [0 0 0 0 1 0 0 0]
 [1 0 0 0 1 0 0 0]]

Есть ли способ выполнить итерацию по этому массиву и для каждого кластера 2x2 из 0 установить все значения в этом кластере = 5?Вот как будет выглядеть вывод.

[[0 1 5 5 1 5 5 1]
 [0 1 5 5 0 5 5 0]
 [0 1 5 5 1 5 5 0]
 [0 0 5 5 1 5 5 0]
 [1 0 5 5 1 5 5 0]]

Мои мысли состоят в том, чтобы использовать расширенное индексирование, чтобы задать для формы 2x2 = 5, но я думаю, что будет очень медленно просто выполнять итерации, например: 1) проверить, является ли массив [x] [y]0 2) проверьте, равны ли соседние элементы массива 0 3) если все элементы равны 0, установите все эти значения на 5.

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

Вот решение, рассматривая массив как блоки.

Сначала вам нужно определить эту функцию rolling_window отсюда https://gist.github.com/seberg/3866040/revisions

Затем разбить массив big, ваш начальный массив, на блоки 2x2, используя эту функцию.Также создайте массив, который имеет индексы каждого элемента в большом и разбейте его аналогично на блоки 2x2.

Затем сгенерируйте логическую маску, в которой блоки размером 2x2, большие, равны нулю, и используйте массив индекса для получения этих элементов.

blks = rolling_window(big,window=(2,2)) # 2x2 blocks of original array
inds = np.indices(big.shape).transpose(1,2,0) # array of indices into big 
blkinds = rolling_window(inds,window=(2,2,0)).transpose(0,1,4,3,2) # 2x2 blocks of indices into big 

mask = blks == np.zeros((2,2)) # generate a mask of every 2x2 block which is all zero 
mask = mask.reshape(*mask.shape[:-2],-1).all(-1) # still generating the mask 


# now blks[mask] is every block which is zero..
# but you actually want the original indices in the array 'big' instead

inds = blkinds[mask].reshape(-1,2).T # indices into big where elements need replacing 
big[inds[0],inds[1]] = 5 #reassign 

Вам нужно проверить это: я не сделал.Но идея состоит в том, чтобы разбить массив на блоки и массив индексов на блоки, затем разработать логическое условие для блоков, использовать их для получения индексов и затем переназначить.

Альтернативой может быть итерация по indblks, как определено здесь, затем тестирование 2x2, полученного от big для каждого элемента indblk, и переназначение при необходимости.

0 голосов
/ 02 декабря 2018

Это моя попытка помочь вам решить вашу проблему.Мое решение может быть подвергнуто справедливой критике.

import numpy as np
from itertools import product
m = np.array((
  [0,1,0,0,1,0,0,1],
  [0,1,0,0,0,0,0,0],
  [0,1,0,0,1,0,0,0],
  [0,0,0,0,1,0,0,0],
  [1,0,0,0,1,0,0,0]))
h = 2
w = 2
rr, cc = tuple(d + 1 - q for d, q in zip(m.shape, (h, w)))
slices = [(slice(r, r + h), slice(c, c + w))
          for r, c in product(range(rr), range(cc))
          if not m[r:r + h, c:c + w].any()]
for s in slices:
    m[s] = 5
print(m)

[[0 1 5 5 1 5 5 1]
 [0 1 5 5 0 5 5 5]
 [0 1 5 5 1 5 5 5]
 [0 5 5 5 1 5 5 5]
 [1 5 5 5 1 5 5 5]]
0 голосов
/ 30 ноября 2018
big_array = [1, 7, 0, 0, 3]

i = 0
p = 0
while i <= len(big_array) - 1 and p <= len(big_array) - 2:
    if big_array[i] == big_array[p + 1]:
        big_array[i] = 5
        big_array[p + 1] = 5
        print(big_array)
    i = i + 1
    p = p + 1

Вывод: [1, 7, 5, 5, 3]

Это пример, а не весь правильный код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...