为啥内置的python sum 函数会这样?

Posted

技术标签:

【中文标题】为啥内置的python sum 函数会这样?【英文标题】:Why is the built-in python sum function behaving like this?为什么内置的python sum 函数会这样? 【发布时间】:2019-06-01 04:49:13 【问题描述】:

我正在尝试编写一个程序来确定 pearson 相关系数与 python 中的总体标准差。我认为这将是非常微不足道的,直到我得到求和的部分 (yi - μy)*(xi - μx)。这是我的完整代码:

def r(x, y):
    mx, my = sum(x) / len(x), sum(y) / len(y)
    sdx, sdy = (sum([(xi-mx)**2 for xi in x]) / len(x))**0.5, (sum([(yi- 
    my)**2 for yi in y]) / (len(y)))**0.5
    res = ((sum([(xi-mx)*(yi-my) for xi in x for yi in y]))/(len(x)*sdx*sdy))**0.5
    return res

我注意到结果非常小,所以我检查了 (xi-mx) 的总和:

sum([(xi-mx) for xi in x])

结果是 -9.769962616701378e-15。以下是列表中的值:

print([(xi-mx) for xi in x])
[3.2699999999999987, 3.0699999999999994, 1.2699999999999987, 1.0699999999999985, 0.9699999999999989, 0.2699999999999987, -0.7300000000000013, -1.7300000000000013, -2.7300000000000013, -4.730000000000001]

谁能解释一下为什么 python 的行为如此奇怪?

【问题讨论】:

舍入点错误。这里的所有都是它的。如果需要,请使用round(number, decimal_points) 看到最后的e-15了吗? @GeeTransit 将 xi 舍入到小数点后 4 位仍然返回 -9.769962616701378e-15... 我认为这也可以解决潜在的浮点错误,并且知道为什么它不起作用 嗯。您用来调用函数的xy 值是什么?我去看看能不能重现这个问题。 @user2357112 是的,每个结果后面都跟着 e 和一个负整数 【参考方案1】:
res = (sum([(xi-mx)*(yi-my) for xi in x for yi in y]))/(len(x)*sdx*sdy)

这不是你认为的那样。在计算皮尔逊相关系数的分子时,(xi - mx) * (yi - my) 应按顺序配对。 使用zip 应该可以解决它。

res = (sum([(xi-mx)*(yi-my) for xi, yi in zip(x, y)]))/(len(x)*sdx*sdy)

这就是我得到的:

def r(x, y):
    mx, my = sum(x) / len(x), sum(y) / len(y)
    sdx, sdy = (sum([(xi-mx)**2 for xi in x]) / len(x))**0.5, (sum([(yi-
    my)**2 for yi in y]) / (len(y)))**0.5
    res = (sum([(xi-mx)*(yi-my) for xi, yi in zip(x, y)]))/(len(x)*sdx*sdy)
    return res

r(x, y) # 0.6124721937208479

for xi in x for yi in y 的真正作用是什么?

>>> x, y = [1, 2, 3], [4, 5, 6]
>>> [(xi, yi) for xi in x for yi in y]
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]

所以有重复发生。 (实际上是生成一个组合列表。)您可以使用zip 将值聚合成对:

>>> [*zip(x, y)]
[(1, 4), (2, 5), (3, 6)]

【讨论】:

这正是我想要的!程序在我改变后工作。我想我犯了一个数学错误,但只是我写得不好。谢谢!【参考方案2】:

您显示的数字之和实际上接近于 0。为什么这很奇怪?事实上,它必须接近于 0。不管 x 以什么值开头,在数学上

sum(xi - mean(x) for xi in x) =
sum(xi for xi in x) - sum(mean(x) for xi in x) =
len(x) * mean(x) - len(x) * mean(x) =
0

数字结果不完全是 0 仅仅是由于浮点舍入错误。

【讨论】:

以上是关于为啥内置的python sum 函数会这样?的主要内容,如果未能解决你的问题,请参考以下文章

python学习笔记011——内置函数sum()

pythone函数基础内置函数学习

python4.3内置函数

为啥 Pydev 会给出内置关键字的语法错误?

python序列序列操作的常用内置函数

python内置函数