问题描述
我有一个3维平面的基础:(u,v)。
我想获得此基础上的所有线性组合,以便基本上遍历整个平面:
对于[0,512 [中的i]和[0,512 [中的j],获得所有(i * u + j * v)。
我需要这样快,因此for循环实际上不是一个选择。 我该如何用Numpy广播做到这一点?
看看 ,我的印象是不可能做...
尝试:
# This is an orthonormal basis but there is no guarantee it is
u = np.array([1, 0, 0])
v = np.array([0, 1, 0])
tmp = np.arange(512)
factors = itertools.combinations(tmp, 2)
pixels = factors[0] * u + factors[1] + v
但是显然这是行不通的。
有解决这个问题的方法吗? 如果是,那又如何?
1楼
将(u,v)与2D索引网格相乘:
ind = np.indices((512, 512))
pixels = ind[0, ..., np.newaxis] * u + ind[1, ..., np.newaxis] * v
>>> %timeit ind = np.indices((512, 512)); pixels = ind[0, ..., np.newaxis] * u + ind[1, ..., np.newaxis] * v
8.06 ms ± 69.8 ?s per loop (mean ± std. dev. of 7 runs, 100 loops each)
将u与一维索引范围相乘,将v与一维索引范围相乘,广播并合并为2D:
i512 = np.arange(512)[:, np.newaxis]
pixels = (i512 * u)[:, np.newaxis, :] + (i512 * v)[np.newaxis, :, :]
>>> %timeit i512 = np.arange(512)[:, np.newaxis]; pixels = (i512 * u)[:, np.newaxis, :] + (i512 * v)[np.newaxis, :, :]
4.06 ms ± 58.6 ?s per loop (mean ± std. dev. of 7 runs, 100 loops each)
2楼
对您的代码进行一些编辑
factors = itertools.product(tmp, tmp)
factors = list(zip(*factors))
factors = np.array(factors)
pixels = factors[0][:, None] * u + factors[1][:, None] + v
首先,存在数学错误:您需要笛卡尔积 ,而不是组合。
现在,实际的语法错误: itertools
生成[(i1, j1), (i2, j2)..]
,而不是numpy数组。
因此,要使最后一行正常工作,您必须
-
zip(*)
将列表转换为(i1, i2), (j1, j2)
格式 - 使它成为一个numpy数组
-
在
factors[0], factors[1]
中是1D的factors[0], factors[1]
向量,添加[:, None]
将其转换为列,以便广播有效。