通过 .reshape(generator) 将一维数组广播到可变 nD 数组的特定维度
Broadcasting a 1D array to a particular dimension of a varying nD array via .reshape(generator)
我有一个 nD 维的形状为 (2,2,2,...n) 的大矩阵,它经常变化。
但是我也收到传入数据,它始终是形状为 (2,) 的一维数组。
现在我想通过重塑将我以前的 nD 维度矩阵与我的一维数组相乘...我还有一个 'index' 我想特别广播和修改的维度。
因此我正在执行以下操作(在循环内):
matrix_nd *= array_1d.reshape(1 if i!=index else dimension for i, dimension in enumerate(matrix_nd.shape))
但是这个生成器作为输入似乎无效。
请注意,维度将始终等于 2,并且只会在我们的序列中放置一次。
例如,如果我们有一个形状为 (2,2,2,2,2) 且索引为 3 的 5D 矩阵;我们希望将一维数组重塑为 (1,1,1,2,1).
有什么想法吗?
提前致谢。
编辑:
所以事实证明我的整个方法都是错误的:
获取我之后的元组似乎仍然将 (2,) 一维数组广播到所有维度。
例如:
我有 (2,2,2) 的 numpy 数组 test_nd.shape
,它看起来像这样:
array([[[1, 1],
[1, 1]],
[[1, 1],
[1, 1]]])
然后我重塑一个 (2,) 1D 数组以仅广播到第 3 个维度:
toBroadcast = numpy.asarray([0,0]).reshape(1,1,2)
其中 toBroadcast 的格式为 array([[[0, 0]]])
然而... test_nd*toBroadcast
returns 结果如下:
array([[[0, 0],
[0, 0]],
[[0, 0],
[0, 0]]])
好像一直在向各个维度广播。有什么想法吗?
你可以像这样定义一个函数
def broadcast_axis(data, ndims, axis):
newshape = [1] * ndims
newshape[axis] = -1
return data.reshape(*newshape)
并像
一样使用它
vector = broadcast_axis(vector, matrix.ndim, 3)
一种方法是排列轴。因此,我们可以将相关轴从 matrix_nd
推到最后一个,让它与一维数组相乘,最后置换轴。因此,给定 axis
,在 matrix_nd
中,我们需要乘以一维数组,它将是 -
np.moveaxis(np.moveaxis(matrix_nd,axis,-1)*array_1d,-1,axis)
同样,我们不需要将一维数组重新整形为 (1,1,1,2,1)
。我们可以将其重塑为相关轴,即 (2,1)
和 broadcasting
仍然有效,因为引导轴是自动广播的。因此,另一种方式是 -
matrix_nd*array_1d.reshape((-1,)+(1,)*(matrix_nd.ndim-axis-1))
我有一个 nD 维的形状为 (2,2,2,...n) 的大矩阵,它经常变化。
但是我也收到传入数据,它始终是形状为 (2,) 的一维数组。
现在我想通过重塑将我以前的 nD 维度矩阵与我的一维数组相乘...我还有一个 'index' 我想特别广播和修改的维度。
因此我正在执行以下操作(在循环内):
matrix_nd *= array_1d.reshape(1 if i!=index else dimension for i, dimension in enumerate(matrix_nd.shape))
但是这个生成器作为输入似乎无效。 请注意,维度将始终等于 2,并且只会在我们的序列中放置一次。
例如,如果我们有一个形状为 (2,2,2,2,2) 且索引为 3 的 5D 矩阵;我们希望将一维数组重塑为 (1,1,1,2,1).
有什么想法吗?
提前致谢。
编辑:
所以事实证明我的整个方法都是错误的: 获取我之后的元组似乎仍然将 (2,) 一维数组广播到所有维度。
例如:
我有 (2,2,2) 的 numpy 数组 test_nd.shape
,它看起来像这样:
array([[[1, 1],
[1, 1]],
[[1, 1],
[1, 1]]])
然后我重塑一个 (2,) 1D 数组以仅广播到第 3 个维度:
toBroadcast = numpy.asarray([0,0]).reshape(1,1,2)
其中 toBroadcast 的格式为 array([[[0, 0]]])
然而... test_nd*toBroadcast
returns 结果如下:
array([[[0, 0],
[0, 0]],
[[0, 0],
[0, 0]]])
好像一直在向各个维度广播。有什么想法吗?
你可以像这样定义一个函数
def broadcast_axis(data, ndims, axis):
newshape = [1] * ndims
newshape[axis] = -1
return data.reshape(*newshape)
并像
一样使用它vector = broadcast_axis(vector, matrix.ndim, 3)
一种方法是排列轴。因此,我们可以将相关轴从 matrix_nd
推到最后一个,让它与一维数组相乘,最后置换轴。因此,给定 axis
,在 matrix_nd
中,我们需要乘以一维数组,它将是 -
np.moveaxis(np.moveaxis(matrix_nd,axis,-1)*array_1d,-1,axis)
同样,我们不需要将一维数组重新整形为 (1,1,1,2,1)
。我们可以将其重塑为相关轴,即 (2,1)
和 broadcasting
仍然有效,因为引导轴是自动广播的。因此,另一种方式是 -
matrix_nd*array_1d.reshape((-1,)+(1,)*(matrix_nd.ndim-axis-1))