考虑以下代码
import numpy as np
a = np.array([1,2])
b = np.array([3,4])
c = [a,b]
np.sum(x for x in c) # array([4,6])
np.sum(c) # 10
处理与生成器表达式不同的列表的理由是什么?
答案 0 :(得分:1)
此:
>>> np.sum(x for x in c)
array([4, 6])
相当于对第一维进行求和:
>>> np.sum(c, axis=0)
array([4, 6])
另一方面,他将总结所有方面:
>>> np.sum(c)
10
文件的相关部分:
np.sum(a, axis=None, ...
给定轴上的数组元素的总和。
axis=None
将汇总输入数组的所有元素。
答案 1 :(得分:1)
引用此拉取请求https://github.com/numpy/numpy/pull/10670
我认为此更改的原始理由是允许以下更改不会破坏此代码
from numpy import * def my_func(n): return sum(i*i for i in range(n))
弃用它的原因:
- sum是唯一一个执行此操作的函数,即使任何所有也都是shadow builtins
- 没有记录
- 与np.array(generator).sum()不一致,已经失败。
答案 2 :(得分:0)
生成器表达式一次生成或生成一个元素。
由于c
有数组a
和b
作为其元素,因此它会在np.sum(x for x in c)
期间将sum应用于各个数组。
np.sum()在展平它们之后总结c的所有元素。
答案 3 :(得分:0)
你有区别的原因是你在第一种情况下迭代一组数组而不是单独的元素。我想合理的解释是Cipher
事先并不知道从生成器得到什么,并分别对每个元素求和。并且,后面的语句将您的数组数组视为矩阵,并默认对其所有元素求和,因为它们都是事先知道的。
您可以通过以下方式获得相同的结果:
numpy
否则,您可以尝试:
assert np.sum(c, axis=0).tolist() == [4, 6]
答案 4 :(得分:0)
在numpy 1.13.3中,numpy.sum()
使用Python的内置sum()
逐个总结生成器的元素。对于类似数组(例如,列表和数组),使用numpy的sum()
的向量化实现(默认情况下使数组变平并且对其元素求和)。
我对理性的猜测:生成器背后的想法是元素被采用并逐个处理。矢量化背后的想法是所有数据理想地一次性采取并且处理并行。所以,这些想法是完全相反的。
现在,如果用户明确地将生成器作为参数提供给numpy.sum()
,那么她明确地希望将生成的元素(示例中的向量[1,2]和[3,4])总结为一个一个,因此,不希望矢量化。
如果用户向numpy.sum()
提供类似数组的参数,则假定她希望应用sum()
的矢量化版本。问题只是应该总结的数组的原始元素。默认情况下,类似于数组的平面化,并且扁平化数组的值(在您的示例中为1,2,3和4)总结。可以使用axis
参数更改此行为。
这就是为什么生成器的处理方式与数组不同。