【发布时间】:2019-08-07 10:08:24
【问题描述】:
我有尺寸为 (100, 100, 16, 16) 的 numpy 数组“测试”,它为 100x100 网格上的点提供了一个不同的 16x16 数组。 我还有一些特征值和向量,其中 vals 具有维度 (100, 100, 16) 和 vecs (100, 100, 16, 16),其中 vecs[x, y, :, i] 将是矩阵的第 i 个特征向量第 i 个特征值 vals[x, y, i] 对应的点 (x, y)。
现在我想在网格上的所有点上取数组的第一个特征向量,与测试矩阵做一个矩阵乘积,然后在所有点上与数组的所有其他特征向量做一个结果向量的标量乘积在网格上并将它们相加。 结果数组的维度应为 (100, 100)。在此之后,我想取数组的第二个特征向量,矩阵将它与 test 相乘,然后将结果与不是第二个的所有特征向量相乘,依此类推,最后我有 16(100 , 100) 或更确切地说是 (100, 100, 16) 数组。到目前为止,我只成功了很多我想避免的 for 循环,但是使用 tensordot 给了我错误的维度,我不知道如何选择 np.dot 函数沿矢量化的轴。 我听说 einsum 可能适合这项任务,但是不依赖 python 循环的一切对我来说都很好。
import numpy as np
from numpy import linalg as la
test = np.arange(16*16*100*100).reshape((100, 100, 16, 16))
vals, vecs = la.eig(test + 1)
np.tensordot(vecs, test, axes=[2, 3]).shape
>>> (10, 10, 16, 10, 10, 16)
编辑:好的,所以我使用 np.einsum 来获得正确的中间结果。
np.einsum('ijkl, ijkm -> ijlm', vecs, test)
但在下一步中,我只想对 vec 的所有其他条目进行标量积。我可以在这个 einsum 形式中实现一些逆 Kronecker delta 吗?或者我现在应该切换回通常的 numpy 吗?
【问题讨论】:
-
使用
np.einsum('ijkl,ijkl->ij',vecs,test)获取矩阵乘积。
标签: python python-3.x numpy linear-algebra