【问题标题】:Sequentially applying a dot product to slices of 3D numpy array依次将点积应用于 3D numpy 数组的切片
【发布时间】:2019-02-16 12:53:20
【问题描述】:

嗨 Stack Overflow 社区,

我有一个形状为 4x4x701 的 3D numpy 数组 Rp,其中 701 个 4x4 切片中的每一个都代表不同时间点的某个数量。我正在尝试有效地将 Givens 旋转矩阵 Q 及其 Hermitian 转置 QH 应用于 701 个切片中的每一个,并且目前正在迭代地执行此操作,如下所示:

for idx in np.arange(Rp.shape[-1]):
    Rp[[j,k],:,idx] = np.dot(Q, Rp[[j,k],:,idx])
    Rp[:,[j,k],idx] = np.dot(Rp[:,[j,k],idx], QH)

但是必须有一种方法可以不迭代地执行此操作(用于 numpy 加速)。我意识到我可以在第一种情况下使用np.dot,但是如果没有一些换位,这对第二种情况不起作用,这似乎会减慢速度。

任何想法将不胜感激!

【问题讨论】:

  • numpy 转置在某种意义上是一种符号方便。它实际上并没有重新排序内存中的数组。所以它实际上并不慢。这是矢量化代码的正确方法。您是否尝试过为解决方案计时?
  • 我建议先尝试使用 1d 向量和 2d 数组进行的操作,我敢打赌您可能会弄明白。你绝对可以通过巧妙地使用np.einsum() 来实现这一点。我建议仔细阅读this blog post(这启发了this SO answer)。但是你也可以为向量化操作随意转置——循环是要你的命,而不是转置。
  • matmul(@ 运算符)在最后 2 个维度上执行 dot。因此,如果您的 Rp 是 (701,4,4) 形状,您可能会执行类似 Q @ Rp @ QH 的操作。我会测试一下细节。
  • @Denziloe 谢谢,这是一个重要的信息。我现在将尝试使用转置。

标签: python numpy multidimensional-array dot-product numpy-slicing


【解决方案1】:

形状的粗略测试;值真的应该更具诊断性:

In [46]: Q = np.eye(4); QH = np.conj(Q)
In [47]: R = np.ones((10,4,4))

In [48]: (Q @ R @ QH).shape
Out[48]: (10, 4, 4)

In [49]: np.einsum('ij,kjl,lm->kil',Q,R,QH).shape
Out[49]: (10, 4, 4)

如果大维度在最后:

In [50]: Rp = R.transpose(1,2,0)
In [51]: Rp.shape
Out[51]: (4, 4, 10)

In [53]: np.einsum('ij,jlk,lm->ilk',Q,Rp,QH).shape
Out[53]: (4, 4, 10)

In [55]: (Q @ Rp.transpose(2,1,0) @ QH).transpose(1,2,0).shape
Out[55]: (4, 4, 10)

我们也可以用tensordot 写这个。

In [58]: np.tensordot(QH,np.tensordot(Q,Rp,(1,1)),(0,1)).shape
Out[58]: (4, 4, 10)

【讨论】:

  • 感谢您花时间编写此示例。你能解释一下你对 tensordot 的使用吗?
  • tensordot 使用 transpose 和 reshape 将数组转换为可以传递给 dot 的数组 - 并根据需要重新整形。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
  • 2018-05-27
  • 2019-07-11
  • 2021-04-22
相关资源
最近更新 更多