在多个阵列上进行Numpy广播

时间:2018-09-17 12:26:53

标签: python arrays numpy

我有一个3维平面的基础:(u,v)。

我想获得以此为基础的所有线性组合,以便基本上遍历整个平面:

对于[0,512 [中的i]和[0,512 [中的j],获得所有(i * u + j * v)。

我需要快速执行此操作,因此for循环并不是真正的选择。我该如何通过Numpy广播做到这一点?

看看https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html,我的印象是不可能做...

尝试:

# 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

但是显然它不起作用。

是否有解决此问题的方法?如果是的话怎么办?

2 个答案:

答案 0 :(得分:2)

将(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)

答案 1 :(得分:1)

对您的代码进行了一些修改

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数组。因此,要使最后一行正常工作,您必须

  1. zip(*)将列表转换为(i1, i2), (j1, j2)格式
  2. 使其成为一个numpy数组
  3. factors[0], factors[1]向量(为 1D )中
  4. 添加[:, None]以将转换为列,以便广播工作。