【问题标题】:Simple subtraction causes a broadcasting issue for different array shapes简单的减法会导致不同数组形状的广播问题
【发布时间】:2015-12-24 05:27:20
【问题描述】:

我尝试使用 link 解决我的问题,描述 numpy 广播,但无济于事。如何减去以下numpy数组:

X = np.array([[[1,2,3,4],[1,2,3,4],[1,2,3,4]],
              [[4,3,2,1],[4,3,2,1],[4,3,2,1]]])
X_mean = np.average(X_, axis=1)

当我执行X - X_mean 时,它会说:

ValueError: operands could not be broadcast together with shapes (2,3,4) (2,4) 

但是X[0] - X_mean[0] 会给出正确的输出:

array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])

【问题讨论】:

    标签: python arrays numpy array-broadcasting


    【解决方案1】:

    您需要保持尺寸对齐,broadcasting 才会发生。你有 -

    In [4]: whos
    Variable   Type       Data/Info
    -------------------------------
    X          ndarray    2x3x4: 24 elems, type `int64`, 192 bytes
    X_mean     ndarray    2x4: 8 elems, type `float64`, 64 bytes
    
    1. X_meanAxis-0 已经与Xaxis-0 对齐,所以一切都很好。

    2. X_meanAxis-1 Xaxis-2 对齐,所以在X_mean 那里加上None/np.newaxis 的新轴,这样axis-1 可以推回axis-2

    让我们验证形状对齐 -

    In [7]: X_mean3D = X_mean[:,None,:]
    
    In [8]: whos
    Variable   Type       Data/Info
    -------------------------------
    X          ndarray    2x3x4: 24 elems, type `int64`, 192 bytes
    X_mean     ndarray    2x4: 8 elems, type `float64`, 64 bytes
    X_mean3D   ndarray    2x1x4: 8 elems, type `float64`, 64 bytes
    

    然后,执行将引入广播的减法 -

    In [5]: X - X_mean[:,None,:]
    Out[5]: 
    array([[[ 0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.]],
    
           [[ 0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.]]])
    

    【讨论】:

    • 或者,可以使用mean 方法的keepdims 参数:result = X - X.mean(axis=1, keepdims=True)
    【解决方案2】:

    作为补充:根据Numpy Broadcasting Rules

    当对两个数组进行操作时,NumPy 会逐元素比较它们的形状。它从尾随维度开始,然后向前推进。两个维度兼容时

    • 他们是平等的
    • 其中一个是 1

    所以最好的办法是以轴 0 上的均值的方式对数据进行整形。

    在你的情况下:

    Y=np.rollaxis(X,1) # reshape (3,2,4)
    

    Y-Y.mean(0)现在直接

    array([[[ 0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.]],
    
           [[ 0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.]],
    
           [[ 0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.]]])
    

    【讨论】:

      猜你喜欢
      • 2019-04-22
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 2018-02-17
      相关资源
      最近更新 更多