简体   繁体   English

通过numpy数组优化迭代以进行邻居检查

[英]Optimize an iteration through a numpy array for neighbours checking

Is there a way to optimize the following iteration with neighbours checking: 有没有一种方法可以通过邻居检查来优化以下迭代:

for i in range(1, A.shape[0]):
    for j in range(1, A.shape[1]):
        v = (A[i, j], A[i-1,j-1], A[i-1, j], A[i, j-1])
        if v == something: print(v)

where A is a (very big) numpy array of 0's and 1's, v and something are tuples (eg (0, 1, 0, 0)). 其中A是一个0和1的(非常大的)numpy数组, vsomething是元组(例如(0,1,0,0))。

Create the test data first: 首先创建测试数据:

import numpy as np
np.random.seed(1)
A = np.random.randint(0, 2, size=(10, 8)).astype(np.uint8)

A: A:

array([[1, 1, 0, 0, 1, 1, 1, 1],
       [1, 0, 0, 1, 0, 1, 1, 0],
       [0, 1, 0, 0, 0, 1, 0, 0],
       [1, 0, 0, 0, 1, 0, 0, 0],
       [1, 1, 1, 1, 1, 0, 0, 0],
       [1, 1, 1, 1, 1, 1, 0, 1],
       [1, 0, 0, 1, 0, 0, 1, 1],
       [1, 0, 1, 0, 0, 1, 1, 0],
       [1, 1, 1, 1, 0, 0, 1, 1],
       [0, 0, 0, 0, 1, 1, 1, 0]], dtype=uint8)

then create an array that use bits to represent neighbours value: 然后创建一个使用位表示邻居值的数组:

a = A[:-1, :-1] << 3
a |= A[:-1, 1:] << 2
a |= A[1:, :-1] << 1
a |= A[1:, 1:]

to check neighbours value of 检查邻居的价值

11
00

you can use: 您可以使用:

a == int("1100", 2)

the output: 输出:

array([[False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [False,  True, False, False,  True, False, False],
       [False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [ True,  True,  True, False, False, False, False]], dtype=bool)

All you need to do is generate the four arrays of boolean conditions. 您需要做的就是生成四个布尔条件数组。 Roughly: 大致:

spot = A == v[0]
upleft = np.roll(A, (1,1), (0,1)) == v[1]
left = np.roll(A, 1, 1) == v[2]
up = np.roll(A, 1, 0) == v[3]

Then you can find the places where all four are true: 然后,您可以找到四个全部都成立的地方:

res = spot & upleft & left & up

This gives you a boolean array which is True wherever all the conditions are met. 这将为您提供一个布尔数组,该布尔数组在所有条件都满足的情况下为True。 You should ignore the first row and column, as they cannot be computed: 您应该忽略第一行和第一列,因为它们无法计算:

res = res[1:,1:]
# or
res[0,:] = False
res[:,0] = False

Here is the convolution based method suggested by @Matt.St in the comments. 这是@ Matt.St在评论中建议的基于卷积的方法。

>>> import numpy as np
>>> from scipy import signal
>>> a = np.random.randint(0, 2, (n, n))
>>> t = np.random.randint(0, 2, (2, 2))
>>> 
>>> 
>>> tt = 2*t[::-1, ::-1] - 1
>>> ts = t.sum()
>>> 
>>> result = signal.convolve2d(a, tt, 'valid') == ts
>>> 
>>> a
array([[1, 0, 1, 0, 1, 0, 0, 1, 0, 1],
       [0, 1, 1, 1, 0, 1, 1, 1, 0, 0],
       [0, 1, 0, 1, 1, 1, 0, 1, 0, 0],
       [0, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 0, 1, 1, 1, 1, 0, 1, 0],
       [1, 1, 0, 0, 1, 0, 0, 1, 1, 1],
       [1, 1, 1, 0, 1, 0, 0, 1, 1, 1],
       [0, 1, 0, 1, 0, 1, 0, 0, 1, 0],
       [0, 0, 0, 1, 1, 0, 0, 1, 0, 1],
       [1, 1, 0, 1, 0, 0, 1, 1, 1, 0]])
>>> t
array([[0, 1],
       [1, 1]])
>>> result
array([[False,  True, False, False, False, False,  True, False, False],
       [False, False, False, False,  True, False, False, False, False],
       [False, False,  True, False, False, False,  True, False, False],
       [ True, False, False, False, False,  True, False, False, False],
       [False, False, False, False, False, False, False,  True, False],
       [False, False, False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False, False, False],
       [False, False, False, False, False, False,  True, False, False]], dtype=bool)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM