在Python中使用numpy/scipy对很小的值取对数

5 投票
4 回答
11590 浏览
提问于 2025-04-16 07:13

我有一个Nx1的数组,这个数组表示一个概率分布,也就是说,所有元素加起来等于1。这个数组是用普通的numpy数组表示的。因为N可能比较大,比如10或者20,所以很多元素的值都非常接近0。当我对这个数组使用log(my_array)的时候,出现了一个错误:“FloatingPointError: invalid value encountered in log”。注意,这个错误是在我故意设置了numpy的错误处理为seterr(invalid='raise')之后出现的。

我该如何解决这个数值问题呢?我想表示与概率分布对应的向量,并对它们取对数,但不想把值四舍五入到0,因为这样我就会计算log(0),这会导致错误。

谢谢。

4 个回答

1

它们离0有多“接近”?Python似乎很乐意计算10的负很大的对数:

>>> log(0.0000000000000000000000000001)
-64.472382603833282

另外,你为什么要计算对数?你打算在计算完之后用它们做什么呢?

2

什么是接近于零的数呢?

>>> np.log(0)
-inf
>>> 0.*np.log(0)
nan
>>> np.log(1e-200)
-460.51701859880916
>>> 1e-200*np.log(1e-200)
-4.6051701859880914e-198

一种解决办法是给所有的概率加上一个小的正数,这样就能让它们离零有一定的距离。

第二种解决办法是专门处理零的情况,比如把0.*np.log(0)替换成结果数组中的零,或者只在概率数组中包含那些概率不为零的点。

3

你可以根据你需要的准确度来去掉一些尾部数据。

eps = 1e-50
array[array<eps]=eps
log(array)

撰写回答