Numpy power returns 负值

Numpy power returns negative value

我想绘制泊松分布并获得 lambda >= 9 的负概率。

此代码为不同的 lambda 生成绘图:

import numpy as np
import matplotlib.pyplot as plt
from scipy.special import factorial

for lambda_val in range(1, 12, 2):

    plt.figure()
    
    k = np.arange(0,20)
    y = np.power(lambda_val, k)*np.exp(-lambda_val)/factorial(k)

    plt.bar(k, y)
    plt.title('lambda = ' + str(lambda_val))
    plt.xlabel('k')
    plt.ylabel('probability')
    plt.ylim([-0.1, 0.4])
    plt.grid()
    plt.show()

请看这两张图:

我认为 Lambda = 5 看起来不错。

Lambda = 9 不是。

我很确定它与 np.power 有关,因为

np.power(11, 9)

给我:-1937019605,而

11**9

给我:2357947691(WolframAlpha 中相同)。

但如果我避免 np.power 并使用

y = (lambda_val**k)*math.exp(-lambda_val)/factorial(k)

为了计算概率,我也得到了负值。我完全糊涂了。谁能解释一下效果或我做错了什么?提前致谢。 :)

您的问题是由于 32 位整数溢出。发生这种情况是因为 Numpy 有时使用 32 位整数编译,即使平台(OS + 处理器)是 64 位平台。出现溢出是因为 Numpy 自动将 Python 解释器的无界整数转换为本机 np.int_ 类型。您可以使用 np.int_ is np.int64 检查此类型是否为 64 位类型。 AFAIK,在 Python Pip 上可用的为 Windows 编译的默认 Numpy 二进制包使用 32 位整数,而 Linux 包之一使用 64 位整数(假设你在 64 -位平台)。

可以使用以下方法轻松重现该问题:

In [546]: np.power(np.int32(11), np.int32(9))
Out[546]: -1937019605

也可以这样解决:

In [547]: np.power(np.int64(11), np.int64(9))
Out[547]: 2357947691

在第二个表达式中,您使用默认类型为 np.int_k,这肯定是您遇到相同问题的原因。希望您可以向 Numpy 指定整数应该更大。请注意,Numpy 有一些隐含的规则来避免溢出,但在不严重影响性能的情况下很难在所有情况下避免它们。这是一个固定的公式:

k = np.arange(0, 20, dtype=np.int64)
y = np.power(lambda_val, k) * np.exp(-lambda_val) / factorial(k)

经验法则是当你得到意想不到的结果时要非常小心隐式转换