使用numpy的sum函数进行广播

时间:2018-05-28 15:14:05

标签: python numpy

我正在阅读有关广播的内容,并试图使用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函数,我不能进行广播吗?

2 个答案:

答案 0 :(得分:4)

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.]])

答案 1 :(得分:0)

你实际上可以进行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])