python numpy中的长(>;2000万个元素)数组求和

python numpy中的长(>;2000万个元素)数组求和,python,numpy,Python,Numpy,我是python和numpy新手,所以如果这个问题还很初级,请原谅! 我有一个负值数组(已排序): 我需要将这个数组添加到它的副本中(但带有正值),以找到平均为零的分布的标准偏差。因此,我做了以下工作: >>>pos=-1*neg >>>pos=pos[::-1] #Just to make it look symmetric for the display bellow! >>>total=np.hstack((neg,pos)) >

我是python和numpy新手,所以如果这个问题还很初级,请原谅! 我有一个负值数组(已排序):

我需要将这个数组添加到它的副本中(但带有正值),以找到平均为零的分布的标准偏差。因此,我做了以下工作:

>>>pos=-1*neg
>>>pos=pos[::-1] #Just to make it look symmetric for the display bellow!
>>>total=np.hstack((neg,pos))
>>>total
[-153.50784302 -153.20001221 -143.1619873  ...,  143.1619873   153.20001221  153.50784302]
>>>total.shape
(25845016,)
到目前为止,一切都很好,但奇怪的是,这个新数组的和不是零:

>>>numpy.sum(total)
11610.6
标准偏差也不是我所期望的,但我想问题的根源是一样的:为什么总和不等于零

当我将此方法应用于一个小数组时;例如[-5,-3,-2]总和变为零。所以我想问题在于数组的长度(超过2000万个元素)。有办法解决这个问题吗


如果有人能在这方面帮助我,我将不胜感激。

如评论中所述,对数百万个等号数字求和会产生浮点舍入问题。一种可能的解决方法是在组合数组中混合正数和负数,以便任何中间结果在求和时始终大致保持在相同的数量级内:

neg = -100*numpy.random.rand(20e6)
pos = -neg
combined = numpy.zeros(len(neg)+len(pos))
combined[::2] = neg
combined[1::2] = pos
现在
combined.sum()
应该非常接近于零


也许这种方法也有助于提高标准偏差计算的精度。

确实
math.fsum(total)
返回
0
?是的!!!哇!你的意思是我根本不应该使用numpy,我错误地认为numpy是处理阵列的最佳工具!!!但是我没有看到任何计算标准偏差的工具。你有什么建议吗?没有。
fsum()
只是为了检查代码是否存在除了在求和过程中丢失精度之外的其他错误。可用于标准偏差。请尝试
np.std(total,dtype=np.float64)
。我想您可能看到了溢出问题。请注意,
sum([1e308,1,-1e308])==0.0
math.fsum([1e308,1,-1e308])==1.0
在进行求和之前,它有助于按数据的绝对值对数据进行排序(特别是在这种情况下,您希望正负贡献相互抵消)。这也有助于先做部分和,比如说100000左右,然后把部分和加在一起。现在和变成了零,均值也变成了零。但非常奇怪的是,标准偏差没有改变。除非
numpy.std()!!!!您需要使用我们描述的方法自己实现
std()
公式中的求和。我编写了一个程序来计算
std()
我自己;求每个值与10000个元素的平均值之差,求和结果,最后除以元素数,求平方根。计算所有>2500万个元素的标准偏差大约需要15分钟,它发现的值与
numpy.std()
的值完全相同(这需要几分之一秒的时间!)。这个数据集是对我的算法的测试:正如我所说,我从一开始就知道标准偏差。我会检查标准偏差的来源,看看它是否正确!我被告知的标准偏差值是在3sigma剪裁之后,我没有被告知,在应用3sigma剪裁之后,我得到了我想要的值。非常感谢大家。
neg = -100*numpy.random.rand(20e6)
pos = -neg
combined = numpy.zeros(len(neg)+len(pos))
combined[::2] = neg
combined[1::2] = pos