* o * o o o * * o * * * * * o o ↓ 2 o 2 o o o 1 1 o 2 1 1 1 1 o o
のような処理を考える。
これは、隣接セルの足し合わせなので、要はコンボリューションを考えれば良い。
2Dのコンボリューションを行う方法としては、「scipy.ndimage.convolve」と
「scipy.signal.convolve」があるが、効率が全然違うので使い分けが重要。
import numpy as np from scipy import ndimage strings = """* o * o o o * * o * * * * * o o""" d = {'*': 0, 'o': 1} lst = [[d[s] for s in line.split()] for line in strings.splitlines()] a = np.array(lst) print(a) kernel = np.array( [ [0, 1, 0], [1, 0, 1], [0, 1, 0] ] ) res = np.where(a==0, ndimage.convolve(a, kernel, mode='constant'), 0) print(res) a = np.concatenate([a]*100000) %timeit signal.convolve(a, kernel, 'same') %timeit ndimage.convolve(a, kernel, mode='constant')
[[0 1 0 1] [1 1 0 0] [1 0 0 0] [0 0 1 1]] [[2 0 2 0] [0 0 1 1] [0 2 1 1] [1 1 0 0]] 10000 loops, best of 3: 38.7 µs per loop 100000 loops, best of 3: 12.5 µs per loop 1 loop, best of 3: 405 ms per loop 10 loops, best of 3: 21.5 ms per loop
ピンバック: 隣接セルの合計(コンボリューション) | 粉末@それは風のように (日記)
ピンバック: 2次元配列で同じ値を持つ隣接要素を見つける – 配列内のフィーチャにラベル付け(Flood fill) | 粉末@それは風のように (日記)