使用np.log(array)时忽略负值
当我想对一个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.])