【问题标题】:Efficiently creating a tensor of diagonal matrices有效地创建对角矩阵的张量
【发布时间】:2019-04-22 01:22:25
【问题描述】:

假设从标量映射到固定维度的矩阵。 如何有效地创建此地图的矢量化版本?

更具体地说,假设有一个带有 n 个条目的常量向量lamb。 给定一个标量 t 我对由

给出的对角矩阵感兴趣
np.diag(np.exp(lamb*t))

使用 numpy. 这将是一个 n 乘以 n 的矩阵。 现在给定一个大小为 m_1 乘以 m_2 的矩阵 T,我想计算为 0 给出的形状 (m_1,m_2,n,n) 的张量 D

D[i,j,:,:] = np.diag(np.exp(lamb*T[i,j]))

如何有效地获得这个张量?

【问题讨论】:

  • 能否添加最小代表性样本数据? t 长什么样子?
  • 标量 t 和矩阵 T 也没有任何限制。或者您所说的“最小代表性样本”是什么意思?
  • 首先lambda*t 似乎不是以t 作为标量的有效语法。其次,用最少的代表性样本,我的意思是t 的一些样本数据和一个可以处理它的有效代码(甚至是循环代码)。
  • 哦,对不起。 lambda这个词在python中是保留的。在本地,我调用了变量 lamb 而不是 ndarray 类型的 lambda。因此,乘以标量被定义为与 t 的逐项乘法。 Paul Panzer 给出的答案产生了我感兴趣的输出。
  • 我们很懒惰。我们不喜欢编造测试用例。而且我们不喜欢单词问题的潜在歧义。好的答案包括工作示例。好的问题也应该如此。

标签: python-3.x numpy vectorization


【解决方案1】:

一种比较直接的方法是使用einsum

例子:

>>> T = np.array([[1,2,3], [4,6,7]])
>>> lam = np.array([1,2,5])
>>> D = np.zeros((*T.shape, n, n))
>>> np.einsum('ijkk->ijk', D)[...] = np.exp(np.multiply.outer(T, lam))
>>> D
array([[[[2.71828183e+00, 0.00000000e+00, 0.00000000e+00],
         [0.00000000e+00, 7.38905610e+00, 0.00000000e+00],
         [0.00000000e+00, 0.00000000e+00, 1.48413159e+02]],

        [[7.38905610e+00, 0.00000000e+00, 0.00000000e+00],
         [0.00000000e+00, 5.45981500e+01, 0.00000000e+00],
         [0.00000000e+00, 0.00000000e+00, 2.20264658e+04]],

        [[2.00855369e+01, 0.00000000e+00, 0.00000000e+00],
         [0.00000000e+00, 4.03428793e+02, 0.00000000e+00],
         [0.00000000e+00, 0.00000000e+00, 3.26901737e+06]]],


       [[[5.45981500e+01, 0.00000000e+00, 0.00000000e+00],
         [0.00000000e+00, 2.98095799e+03, 0.00000000e+00],
         [0.00000000e+00, 0.00000000e+00, 4.85165195e+08]],

        [[4.03428793e+02, 0.00000000e+00, 0.00000000e+00],
         [0.00000000e+00, 1.62754791e+05, 0.00000000e+00],
         [0.00000000e+00, 0.00000000e+00, 1.06864746e+13]],

        [[1.09663316e+03, 0.00000000e+00, 0.00000000e+00],
         [0.00000000e+00, 1.20260428e+06, 0.00000000e+00],
         [0.00000000e+00, 0.00000000e+00, 1.58601345e+15]]]])

您可以使用out 关键字加快速度以避免复制:

np.exp(np.multiply.outer(T, lam), out=np.einsum('ijkk->ijk', D))

【讨论】:

  • 谢谢!像这样的东西正是我想要的。
  • 无法申请np.multiply.outer,必须改为np.multiply.fun.outer
猜你喜欢
  • 1970-01-01
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
相关资源
最近更新 更多