[英]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数组, v
和something
是元组(例如(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.