代码如下
import numpy as np
data = np.random.randint(0, 10, 12).reshape(3, 4)
print(data)
h, w = data.shape[:2]
dataMask = np.zeros((h, w, 10), np.int)
r = 2
for i in range(h):
for j in range(w):
for ir in range(i - r, i + r):
for jr in range(j - r, j + r):
if ir >= 0 and ir < h and jr >= 0 and jr < w:
dataMask[i, j, data[ir, jr]] += 1
print(dataMask)
我有一个形状(h,w)的numpy数组“数据”。它的元素是int number∈[0,10)。
我创建一个形状为(h,w,10)的数组dataMask。 dataMask [i,j,k]表示数据区域内值为k的点数。数据中的该区域的中心为(i,j),r = 2,为正方形。
如何在代码中向量化这些for循环?谢谢!
最佳答案
这是使用cumsum
的一种方法:
import numpy as np
data = np.random.randint(0, 10, 1200).reshape(30, 40)
print(data)
h, w = data.shape[:2]
dataMask = np.zeros((h, w, 10), np.int)
r = 20
from time import time
T = []
T.append(time())
for i in range(h):
for j in range(w):
for ir in range(i - r, i + r):
for jr in range(j - r, j + r):
if ir >= 0 and ir < h and jr >= 0 and jr < w:
dataMask[i, j, data[ir, jr]] += 1
T.append(time())
m1 = np.zeros((h, w, 10), np.int)
np.put_along_axis(m1, data[...,None], 1, 2)
m2 = np.empty_like(m1)
m1 = m1.cumsum(1)
m2[: ,:-r+1] = m1[:, r-1:]
m2[:, -r+1:] = m1[:, -1, None]
m2[:, r+1:] -= m1[:, :-r-1]
m2 = m2.cumsum(0)
m1[:-r+1] = m2[r-1:]
m1[-r+1:] = m2[-1, None]
m1[r+1:] -= m2[:-r-1]
T.append(time())
assert (dataMask==m1).all()
print(np.diff(T))
使用
h,w,r = 30,40,20
运行的示例# time [seconds] used by
# OP cumsum
[9.23162699e-01 3.41892242e-04]
关于python - 如何在Python中为循环矢量化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56374848/