Python的sum函数返回的结果与NumPy的numpy.sum函数不同

5

Numpy的sum函数返回了正确的预期结果,但默认的Python sum函数没有(至少对于uint8数据类型不是,这使情况更加混乱):

In [1]: import numpy as np                                                      

In [2]: x = np.random.randint(2, size = (1000,100))                             

In [3]: x                                                                       
Out[3]: 
array([[1, 1, 0, ..., 0, 1, 1],
       [1, 1, 1, ..., 0, 0, 0],
       [1, 1, 0, ..., 1, 0, 1],
       ...,
       [1, 0, 0, ..., 1, 0, 1],
       [0, 0, 1, ..., 0, 1, 1],
       [1, 1, 0, ..., 1, 1, 1]])

In [4]: np.sum(x)                                                               
Out[4]: 50318

In [5]: sum(sum(x))                                                             
Out[5]: 50318

In [6]: x = x.astype('uint8')                                                   

In [7]: np.sum(x)                                                               
Out[7]: 50318

In [8]: sum(sum(x))                                                             
Out[8]: 16014

好像是整数溢出的问题,但我无法确定具体在哪里。 - Mad Physicist
你尝试过使用更小的数组吗?比如你可以打印出来并手动计算以验证结果。 - Dan
我在几个小数组上尝试了一下(Python内置的sum函数),对于这些数组它是有效的。 - WalksB
1个回答

4

当您指定uint8时,您告诉numpy每个元素使用8位。 8位中可以存储的最大数字是255。 因此,当您进行求和运算时可能会发生溢出。
实际例子:

>>> arr = np.array([[255],[1]],dtype=np.uint8)
>>> arr
array([[255],
       [1]], dtype=uint8)
>>> sum(arr)
array([0], dtype=uint8)
>> arr[0]+arr[1]
array([0], dtype=uint8)

请注意,在这种情况下,sum(arr) 对应于 arr[0] + arr[1]。正如文档中所述:

当使用整数类型时,算术运算是模数的,溢出不会引发错误。


为什么在这种情况下np.sum不会溢出? - Dan
1
似乎会自动转换为np.uint64 - abc
1
type(np.sum(x)) 返回 <class 'numpy.uint64'> 但我发现 type(sum(sum(x))) 返回 <class 'numpy.int64'>,因此它也将其转换为大整数,所以仍然不清楚为什么一个会溢出而另一个不会? - Dan
1
内部求和出现了溢出:type(sum(arr)) <class 'numpy.ndarray'>。实际上,np.sum(sum(arr)) 也会返回错误的结果。np.sum 应该是逐元素的,而内部的 sum() 则会在数组上使用加法操作。 - abc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接