Python/numpy 定位运行时警告
我有一个在应用服务器上运行的numpy脚本,这个脚本会被调用成千上万次,但偶尔会出现一次运行时警告:
/usr/local/lib/python2.7/dist-packages/scipy/stats/stats.py:2417: RuntimeWarning: invalid value encountered in double_scalars
r = (r_num / r_den)
- 我不确定这个警告是在哪里出现的。
- 我也不知道为什么会出现这个警告。
- 这个警告对代码有什么影响吗?看起来一切都正常,单元测试也通过了。
不过,我不太确定我是不是在看正确的地方,因为这个警告出现的几率不到1%。
我该怎么做才能让Python打印出警告出现的位置呢?
3 个回答
在哪里:查看代码
r = (r_num / r_den)
这只在 两个地方 出现于 scipy;
linregress
和pearsonr
在stats.py
文件中。pearsonr
在mstats_basic.py
文件中。
为什么:一个 double_scalar 是一个单独的 double
,而不是一个 numpy 数组。我在想,在某些调用中,r_num
和/或 r_den
可能是一个单一的(无效的)浮点数。但它不是零,因为零并不是无效的数字,这样的话会引发一个 ZeroDivisionError 异常。当计算返回 NaN 时,通常会发出无效的警告。
把警告变成一个异常:
import warnings
warnings.simplefilter('error')
这样的话,就会出现一个错误,你可以看到错误的详细信息。
如果你在脚本的开头放入
np.seterr(all='raise')
这段代码,程序会抛出异常而不是仅仅给出警告。这样会让你的脚本停止运行,并显示一个详细的错误追踪信息,这样你就能知道错误发生在哪里。
接着,你可以在代码中抛出异常的那一行周围加上一个 try...except
结构,然后在 except
部分记录相关变量的值。
另外,你提到的运行时警告显示这个警告是在 stats.py
的第2417行产生的。这似乎是在 pearsonr
函数中。用谷歌搜索“invalid value encountered in double_scalars”可以找到这个问题,它提到
from scipy.stats.stats import pearsonr
X = [4, 4, 4, 4, 4, 4]
Y = [4, 5, 5, 4, 4, 4]
pearsonr(X, Y)
会引发运行时警告。这表明你偶尔会用一些输入调用 pearsonr
,导致出现除以零的情况(正如用户3453425所说)——可能是因为某个输入是常数,因此标准差为零。
在这种情况下,pearsonr(X, Y)
会返回 (nan, 1.0)
。所以要确保你处理好皮尔逊相关系数未定义的情况(即 nan
)。