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

wil*_*yth 6 python dataframe python-3.x

我正在总结一系列值,但根据我的做法,我会得到不同的结果。我尝试过的两种方法是:

sum(df['series'])

df['series'].sum()
Run Code Online (Sandbox Code Playgroud)

为什么他们会返回不同的值?

示例代码。

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
Run Code Online (Sandbox Code Playgroud)

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

kay*_*ya3 6

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

  • “真实”总和是106,但这无法表示,因为我们只允许使用两位有效数字;
  • “正确”答案是110,因为这是四舍五入到 2 sf 的“真实”总和;
  • 但是,如果我们天真地将数字按顺序相加,我们将首先执行 100 + 1 = 100 (到 2 sf),然后 100 + 1 = 100 (到 2 sf),依此类推,直到最终结果为100

“正确”答案可以通过将数字从小到大相加得出;1 + 1 = 2,然后 2 + 1 = 3,然后 3 + 1 = 4,然后 4 + 1 = 5,然后 5 + 1 = 6,然后 6 + 100 = 110(至 2 平方英尺)。然而,即使这在一般情况下也不起作用;如果有超过一百个 1,那么中间和就会开始不准确。您可以通过始终添加最小的两个剩余数字来做得更好。

Python的内置sum函数使用朴素算法,而df['series'].sum()方法使用更精确的算法,具有较低的累积舍入误差。来自pandas 使用的numpy 源代码:

对于浮点数,sum(和 np.add.reduce)的数值精度通常受到直接将每个数字单独添加到结果中的限制,从而导致每一步中的舍入误差。然而,numpy 通常会使用数值上更好的方法(部分成对求和),从而在许多用例中提高精度。当没有给出时,总是提供这种改进的精度axis

math.fsum 函数使用的算法仍然更准确:

与 NumPy 相比,Python 的math.fsum函数使用更慢但更精确的求和方法。

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