python-3.x - Numpy将数组减少到给定的形状
问题描述
我正在尝试编写一个函数,将 numpy ndarray 减少到给定的形状,从而有效地“广播”数组。例如,使用 add 作为通用函数,我想要以下结果:
- A = [1, 2, 3, 4, 5],reduce_shape = (1,) -> [1+2+3+4+5] = [15](轴上的总和=0)
- A = [[1,2], [1,2]], reduce_shape = (2,) -> [1+1, 2+2] = [2, 4](轴上的总和=0)
- A = [[1,2], [1,2]],reduce_shape = (1,) -> [1+2+1+2] = [6](轴总和=(0,1))
- A = [[[1,2], [1,2]], [[1,2], [1,2]]], reduce_shape = (2,2) -> [[1+1, 2+2 ], [1+1, 2+2]] = [[2,4], [2,4]] (轴上的总和=0)
这是我想出的解决方案:
def unbroadcast(A, reduced_shape):
fill = reduced_shape[-1] if reduced_shape else None
reduced_axes = tuple(i for i, (a,b) in enumerate(itertools.zip_longest(A, shape, fillvalue=fill)) if a!=b)
return np.add.reduce(A, axis=reduced_axes).reshape(shape)
但这感觉不必要地复杂,有没有办法依靠 Numpy 的公共 API 来实现呢?
解决方案
目前尚不清楚这如何是“非广播”。
进行计算的直接方法是使用 的axis
参数sum
:
In [124]: np.array([1,2,3,4,5]).sum()
Out[124]: 15
In [125]: np.array([[1,2],[1,2]]).sum(axis=0)
Out[125]: array([2, 4])
In [126]: np.array([[1,2],[1,2]]).sum(axis=(0,1))
Out[126]: 6
In [128]: np.array([[[1,2], [1,2]], [[1,2], [1,2]]]).sum(axis=0)
Out[128]:
array([[2, 4],
[2, 4]])
我用reduce
的不多,但看起来axis也一样:
In [130]: np.add.reduce(np.array([1,2,3,4,5]))
Out[130]: 15
In [132]: np.add.reduce(np.array([[[1,2], [1,2]], [[1,2], [1,2]]]),axis=0)
Out[132]:
array([[2, 4],
[2, 4]])
但我还没有弄清楚从你的价值观reduced_shape
到必要axis
价值观的逻辑。对于像 (2,) 和 (2,2,2) 这样的形状,当您说将形状缩小到 (2,2) 时,可能会产生歧义。如果您使用示例数组,例如np.arange(24).reshape(2,3,4)