假设我有两个表示图片中像素的数组。
我想在“扫描”后者时构建一个较小图片和较大图片的像素的张量积数组。“扫描”是指在使用原始图片创建叠加层时对行和列进行迭代。
例如,可以以四种不同的方式将 2x2 图片叠加在 3x3 之上,因此我想生成一个包含匹配像素张量积的四元素数组。
Tensordot 是通过将 a[i,j] 与 b[i,j] 逐元素相乘并将各项求和来计算的。
请检查此代码:
import numpy as np
a = np.array([[0,1,2],
[3,4,5],
[6,7,8]])
b = np.array([[0,1],
[2,3]])
shape_diff = (a.shape[0] - b.shape[0] + 1,
a.shape[1] - b.shape[1] + 1)
def compute_pixel(x,y):
sub_matrix = a[x : x + b.shape[0],
y : y + b.shape[1]]
return np.tensordot(sub_matrix, b, axes=2)
def process():
arr = np.zeros(shape_diff)
for i in range(shape_diff[0]):
for j in range(shape_diff[1]):
arr[i,j]=compute_pixel(i,j)
return arr
print(process())
计算单个像素非常容易,我所需要的只是 a 中的起始位置坐标。从那里我匹配b的大小并做一个 tensordot 产品。
但是,因为在迭代行和列时我需要对每个x 和 y位置重新执行此操作,所以我不得不使用循环,这当然不是最佳的。
在下一段代码中,我尝试利用 tensordot 的一个方便的特性,它也接受张量作为参数。换句话说,我可以为 a 的不同组合提供一个数组数组,同时保持b相同。
尽管为了创建一个上述组合的数组,我想不出比使用另一个循环更好的方法,在这种情况下听起来很傻。
def try_vector():
tensor = np.zeros(shape_diff + b.shape)
for i in range(shape_diff[0]):
for j in range(shape_diff[1]):
tensor[i,j]=a[i: i + b.shape[0],
j: j + b.shape[1]]
return np.tensordot(tensor, b, axes=2)
print(try_vector())
注意:张量大小是两个元组的总和,在这种情况下给出 (2, 2, 2, 2)
然而无论如何,即使我制作了这样的阵列,它的尺寸也太大了,无法实际使用。对于 1000x1000 的图片执行此操作,可能会消耗所有可用内存。
那么,还有其他方法可以避免这个问题中的循环吗?