python - 沿特定维度从 ndarray 中减去矩阵而不重塑
问题描述
假设我有一个 2 x 2 x 100 的 ndarrayahat
和一个 2 x 2 的矩阵A
。从大小为 100 的维度中减去 2 x 2 矩阵而不循环或重塑的最 Pythonic 方法是什么?
for k in range(ahat.shape[2]):
ahat[:,:,k] = ahat[:,:, k] - A
我尝试使用np.apply_over_axes
但无法让它工作。更一般地说,如果我有两个兼容形状的 ndarray,就像上面的例子一样,沿着特定维度操作的首选方式是什么。例如,我可能想将每个 2x2 矩阵相乘ahat
,A
或者我可能想np.linalg.inv
沿大小为 100 的维度应用。
解决方案
提升A
为形状数组 (2,2,1),然后NumPy 广播将完成剩下的工作:
ahat -= A[..., None]
A[..., None]
相当于A[..., np.newaxis]
。它将长度为 1 的新轴添加到数组中。由于ahat
具有形状 (2,2,100),并且A[..., None]
具有形状 (2,2,1),NumPy 广播会将两个数组提升为兼容的形状 (2,2,100)(但以一种内存效率高的方式,实际上不会将值A
从更大的数组)。
更一般地,请注意 NumPy 广播会自动将新轴添加到任何 NumPy 数组形状的左侧。因此,例如,对于任何基本的 NumPy 算术运算(如加法或乘法A
),如果涉及算术运算的其他数组是 3 维的(甚至 (1 ,1,2,2) 如果另一个数组是 4 维的)。上面,我们需要A[..., None]
显式添加一个新轴,因为我们希望新轴位于形状的右侧。
对于矩阵乘法,您通常会使用np.dot
、 或np.einsum
、 或np.tensordot
。其中一些函数,例如np.einsum
,np.tensordot
允许您指定希望在矩阵乘法中使用的轴(因此您不需要显式添加新轴)。例如,要矩阵乘以ahat
和A
,您可以使用
np.tensordot(ahat, A, axes=[[1], [0]])
或者
np.einsum('ijk,jl->ikl', ahat, A)
这将沿 1 轴的ahat
值与沿 0 轴的值相乘A
,然后求和为乘积。
推荐阅读
- eslint - 如何使用 testing-library/no-node-access 访问 props.children
- php - 清除事件 ID 并调用新的事件 ID 而无需刷新页面
- postgresql - EF Core 使用对象内部对象和 FK 查询 DTO
- reactjs - 你应该在 HOC 组件中访问 redux 存储吗?
- javascript - 为什么我收到错误“SyntaxError: Unexpected keyword 'else' in if elseif elseif else
- php - 在受保护的 dataProvider 方法中获取固定装置
- flutter - 更改选项卡不会重建列表
- mysql - 如果在 DB 服务器不可用时尝试第一次查询,则 Devart/EFCore 永久失败
- java - Java备份MySQL数据库只会将备份文件保存到根目录,否则会失败
- c# - 我希望它在单独打开 exe 文件时关闭