我有一个大型代码,根据从probability density function(PDF)获取的概率,在一个点上对数组中的值进行采样。
要做到这一点,我使用的numpy.random.choice工作正常,直到numpy 1.8.0
。这是一个MWE(文件pdf_probs.txt
可以下载here):
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)
问题是,在使用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
鉴于使用非常小的浮点数时出现的小偏差,PDF概率的总和将不会总和为 1.
从我可以收集到的numpy
(1.8.0
}的早期版本显然比新1.9.0
版本具有更大的容差,但我可能错了。
为什么这适用于numpy 1.8.0
但不适用于1.9.0
?如何使我的代码能够使用新的1.9.0
版本?
答案 0 :(得分: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])