numpy 1.9.0:ValueError:概率不总和为1

Gab*_*iel 12 python arrays random numpy floating-accuracy

我有一个大代码,它根据概率密度函数(PDF)中的概率在一个点上对数组中的值进行采样.

要做到这一点,我使用numpy.random.choice直到很好numpy 1.8.0.这是一个MWE(文件pdf_probs.txt可以在这里下载):

import simplejson
import numpy as np

# Read probabilities from file.
f = open('pdf_probs.txt', 'r')
probs = simplejson.load(f)
f.close()

print sum(probs)  # <-- Not *exactly* 1. but very close: 1.00000173042
# Define array.
arr = np.linspace(1., 100., len(probs))

# Get samples using the probabilities in probs.
samples = np.random.choice(arr, size=1000, replace=True, p=probs)
Run Code Online (Sandbox Code Playgroud)

问题是用numpy 1.9.0上面的代码测试后失败并出现错误:

Traceback (most recent call last):
  File "numpy_180_vs_190_np_random_choice.py", line 13, in <module>
    samples = np.random.choice(arr, size=1000, replace=True, p=probs)
  File "mtrand.pyx", line 1083, in mtrand.RandomState.choice (numpy/random/mtrand/mtrand.c:10106)
ValueError: probabilities do not sum to 1
Run Code Online (Sandbox Code Playgroud)

考虑到使用非常小的浮点数时出现的小偏差,PDF概率的总和将不会精确到1.

从我可以收集到的,以前版本的numpy(1.8.0)显然比新1.9.0版本具有更大的容差,但我可能是错的.

为什么这适用numpy 1.8.0但不适用1.9.0?如何使我的代码与新1.9.0版本一起使用?

DSM*_*DSM 16

我认为1.7e-6是一个足够大的相对误差,值得抱怨.但是,如果您确信错误可以忽略不计,则可以轻松地重新规范化:

>>> probs = np.array(probs)
>>> probs /= probs.sum()
>>> probs.sum()
1.0
>>> samples = np.random.choice(arr, size=1000, replace=True, p=probs)
>>> samples[:5]
array([  1.37635054,   1.1287515 ,   1.7229892 ,  19.8967587 ,   2.07953181])
Run Code Online (Sandbox Code Playgroud)

  • 只是给仍然遇到麻烦的人一个注释。与上面类似,将源数组的数据类型(dtype)设置为np.float64,而不是32位float,显然也不是int。对于 32 位浮点数,标准化(除以总和)时可能会出现 1e-7 的误差。这是一个足够大的错误,足以导致 numpy 引发异常。 (2认同)