使用np.log(array)时忽略负值

4 投票
3 回答
15307 浏览
提问于 2025-04-18 14:53

当我想对一个numpy数组中的特定列取对数时,比如说用 logSFROIIdC = np.log(data_dC[:, 9]),编译器会报错:

-c:13: RuntimeWarning: divide by zero encountered in log.

我知道为什么会出现这个错误,也就是对负数取对数会出错,像log(-1)就是数学错误。

不过,我想要写一些代码,能够跳过数组中那些会导致错误的值,这样就可以完全忽略那一行数据,让这一列的数据可以再次使用。

我尝试了各种方法,现在最后一次求助社区。

3 个回答

2

一个简单的方法是先限制数值不要变成负数。这里可以用到 np.clip 这个函数。

你可以这样写:positive_array = np.clip(array, some_small_positive_value, None),这样就能确保你的数组里没有负值。不过,我不太确定把数值调整得接近零是否符合你的需求。

3

你还可以使用一个“掩码数组”,这样在你进行 np.log() 计算后,NumPy 会自动处理无效值。

a = np.array([1,2,3,0,4,-1,-2])
b = np.log(np.ma.array(a))

print(b.sum())
# 3.17805383035

这里的 np.ma.array(a) 是在创建一个没有被掩盖的数组。它之所以有效,是因为 NumPy 会自动把计算中出现的 inf或者任何无效值)标记为掩盖元素。

另外,你也可以自己创建掩码(我推荐这样做),像这样:

a = np.ma.array(a, mask=(a<=0))
9

你可以通过 np.seterr 来控制这个行为。下面是一个例子。

首先,告诉 numpy 去 忽略 无效的值:

In [4]: old = np.seterr(invalid='ignore')

现在 log(-1) 不会产生警告了:

In [5]: x = np.array([-1.,1])

In [6]: np.log(x)
Out[6]: array([ nan,   0.])

如果想恢复之前的设置:

In [7]: np.seterr(**old)
Out[7]: {'divide': 'warn', 'invalid': 'ignore', 'over': 'warn', 'under': 'ignore'}

这时我们又会收到警告:

In [8]: np.log(x)
/Users/warren/anaconda/bin/ipython:1: RuntimeWarning: invalid value encountered in log
  #!/Users/warren/anaconda/python.app/Contents/MacOS/python
Out[8]: array([ nan,   0.])

还有一个上下文管理器 np.errstate。比如说,

In [10]: with np.errstate(invalid='ignore'):
   ....:     y = np.log(x)
   ....:     

In [11]: y
Out[11]: array([ nan,   0.])

撰写回答