【问题标题】:Broadcasting using numpy's sum function使用 numpy 的 sum 函数进行广播
【发布时间】:2018-05-28 15:14:04
【问题描述】:

我正在阅读有关广播的内容,并试图使用 numpy 的 sum 函数来理解它。

我创建了两个矩阵:

m1 = np.array([[1,2,3],[4,5,6]]) # 3X2
m2 = np.array([[1],[2]]) # 2X1

当我将以上两个添加为:

m1 + m2

广播是在列向量[1],[2] 复制自身等于m1 矩阵内的列数时完成的。是否也可以使用np.sum(m1,m2) 观看广播?我认为m1 + m2np.sum(m1,m2) 之间没有区别。但目前np.sum(m1,m2) 抛出错误TypeError: only integer scalar arrays can be converted to a scalar index

如果我使用它的sum 函数,我不能让 numpy 执行广播吗?

【问题讨论】:

  • m1 + m2 等同于 numpy.add(m1, m2) - 不等同于 numpy.sum(m1, m2)

标签: python numpy


【解决方案1】:

numpy.sum 不添加两个数组,它计算数组的一个(或多个,或默认情况下为所有)轴的总和。第二个参数是要对哪个轴求和,而多维数组对此不起作用。

这些是numpy.sum 工作原理的示例:

m1 = np.arange(12).reshape((3,4))
# sum all entries
np.sum(m1) # 66
# sum along the first axis, getting a result for each column
np.sum(m1, 0) # array([12, 15, 18, 21])

m2 = np.arange(12).reshape((2,3,2))
# sum along two of the three axes
m2.sum((1,2)) # array([15, 51])

您可能正在寻找的是numpy.add。这将两个数组相加(就像+),但允许添加一些约束(当给它一个out 数组时,您可以屏蔽某些字段,这样它们就不会被添加的结果填充)。否则,如果您知道 numpy 广播规则,它会按照您期望的方式运行:

m1 = np.array([[1,2,3],[4,5,6]]) # 3X2
m2 = np.array([[1],[2]]) # 2X1
m1 + m2
# array([[2, 3, 4],
#        [6, 7, 8]])

np.add(m1, m2)
# array([[2, 3, 4],
#        [6, 7, 8]])

这里有一个更花哨的用法示例:

m1 = m1.astype(float)
m1[1, 1] = np.inf
m1
# array([[  1.,   2.,   3.],
#        [  4.,  inf,   6.]])
out = np.zeros_like(m1)
where = np.ones_like(m1, dtype=bool)
where[1, 1] = False # don't want that infinity in the sum
np.add(m1, m2, out, where=where)
# array([[ 2.,  3.,  4.],
#        [ 6.,  0.,  8.]])

【讨论】:

    【解决方案2】:

    你实际上可以让sum广播:

    >>> import numpy as np
    >>> 
    >>> a, b, c = np.ogrid[:2, :3, :4]
    >>> d = b*c
    >>> list(map(np.shape, (a, b, c, d)))
    [(2, 1, 1), (1, 3, 1), (1, 1, 4), (1, 3, 4)]
    >>> 
    >>> a+b+c+d
    array([[[ 0,  1,  2,  3],
            [ 1,  3,  5,  7],
            [ 2,  5,  8, 11]],
    
           [[ 1,  2,  3,  4],
            [ 2,  4,  6,  8],
            [ 3,  6,  9, 12]]])
    >>> np.sum([a, b, c, d])
    array([[[ 0,  1,  2,  3],
            [ 1,  3,  5,  7],
            [ 2,  5,  8, 11]],
    
           [[ 1,  2,  3,  4],
            [ 2,  4,  6,  8],
            [ 3,  6,  9, 12]]])
    

    我怀疑这会创建一个 dtype 对象的 4 元素数组,然后将实际求和委托给元素数组。

    不幸的是,array 工厂有时会反复无常地使用这种数组数组:

    而且,事实上,我们可以使用一个已知的示例来击败np.array 来绊倒np.sum,即使np.array 中似乎没有发生实际错误:

    >>> np.sum([np.arange(3), 1]) # fine
    array([1, 2, 3])
    >>> np.sum([1, np.arange(3)]) # ouch!
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/paul/lib/python3.6/site-packages/numpy/core/fromnumeric.py", line 1882, in sum
        out=out, **kwargs)
      File "/home/paul/lib/python3.6/site-packages/numpy/core/_methods.py", line 32, in _sum
        return umr_sum(a, axis, dtype, out, keepdims)
    ValueError: setting an array element with a sequence.
    

    因此,总的来说,使用内置 Python sum 可能会更好:

    >>> sum([a, b, c, d])
    array([[[ 0,  1,  2,  3],
            [ 1,  3,  5,  7],
            [ 2,  5,  8, 11]],
    
           [[ 1,  2,  3,  4],
            [ 2,  4,  6,  8],
            [ 3,  6,  9, 12]]])
    >>> sum([1, np.arange(3)])
    array([1, 2, 3])
    >>> sum([np.arange(3), 1])
    array([1, 2, 3])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-12
      • 2017-06-18
      • 1970-01-01
      相关资源
      最近更新 更多