Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我不明白为什么sum(df[';series';])!=df[';系列';].sum()_Python_Python 3.x_Dataframe - Fatal编程技术网

Python 我不明白为什么sum(df[';series';])!=df[';系列';].sum()

Python 我不明白为什么sum(df[';series';])!=df[';系列';].sum(),python,python-3.x,dataframe,Python,Python 3.x,Dataframe,我在一系列中求和,但是根据我的方式,我得到不同的结果。我尝试过的两种方法是: sum(df['series']) df['series'].sum() 为什么它们会返回不同的值 示例代码 s = pd.Series([ 0.428229 , -0.948957 , -0.110125 , 0.791305 , 0.113980 ,-0.479462 ,-0.623440 ,-0.610920 ,-0.135165 , 0.090192]) print(s.sum()

我在一系列中求和,但是根据我的方式,我得到不同的结果。我尝试过的两种方法是:

sum(df['series'])

df['series'].sum()
为什么它们会返回不同的值

示例代码

s = pd.Series([
0.428229
 , -0.948957
 , -0.110125
 ,  0.791305
 ,  0.113980
 ,-0.479462
 ,-0.623440
 ,-0.610920
 ,-0.135165
 , 0.090192])

 print(s.sum())
 print(sum(s))

 -1.4843630000000003
 -1.4843629999999999

这里的差异非常小,但是在一个有几千个值的数据集中,它变得非常大。

浮点数只能精确到一定数量的有效数字。想象一下,如果您的所有数字(包括中间结果)仅精确到两个有效数字,并且您想要列表的总和
[100,1,1,1,1,1]

  • “真实”总和为106,但这无法表示,因为我们只允许两个有效数字
  • “正确”答案是110,因为这是四舍五入到2 s.f的“真实”总和
  • 但是如果我们天真地按顺序添加数字,我们将首先执行100+1=100(到2 s.f.),然后执行100+1=100(到2 s.f.),依此类推,直到最终结果是100
“正确”的答案可以通过从最小到最大的数字相加来实现;1+1=2,然后2+1=3,然后3+1=4,然后4+1=5,然后5+1=6,然后6+100=110(到2 s.f.)。然而,即使这样在一般情况下也不起作用;如果超过100个1,那么中间的总和将开始不准确。如果总是将剩下的两个最小的数字相加,您可以做得更好

Python内置的
sum
函数使用朴素算法,而
df['series'].sum()方法使用更精确的算法,累积舍入误差更低,熊猫使用的是:

对于浮点数,求和的数值精度(和
np.add.reduce
)通常通过直接添加每个数字进行限制 在每一步中,分别计算导致舍入误差的结果。 但是,numpy通常会使用数值上更好的方法(部分 成对求和)在许多用例中提高了精度。 当未给出
时,始终提供这种改进的精度

使用更精确的算法:

与NumPy相反,Python的
math.fsum
函数使用了一个较慢但不太实用的 更精确的求和方法


对于您的列表,
math.fsum
的结果是
-1.484363
,这是正确的四舍五入答案。

请提供一个工作示例,说明这是一种不同的行为。二进制浮点数表示很棘手。我会选择
sum(s*10**10)/10**10
。顺便说一句,
(s*10**10)。sum()/10**10==sum(s*10**10)/10**10
真的
。更高的精度是在求和过程中跟踪中间结果,以最小化精度损失。math.fsum=-1.484363计算机上的浮点运算本质上是不精确的。建议您检查两个和是否近似相等,而不是完全相等。请参阅Oracle数字计算指南中的问题和这篇文章,该指南题为“每个计算机科学家都应该知道的浮点运算”。这篇文章很棒。此外还包括Python、Numpy、数学。fsum等。结论是数学。fsum是最准确但速度最慢的方法。