静音 numba 警告

Silencing numba warning

我有一个 numba 装饰函数,它被另一个 class 方法调用。它一直给我弃用警告。为了让它静音,我到目前为止已经尝试过:

(1) 添加@jit(warn=False),但抛出选项不可用的错误

(2) 试图用 warning.catch_warnings()

捕捉警告

None 似乎有效,有趣的是,如果我在调试控制台中执行函数和 运行 之前中断相同的语句(with warnings.catch_warnings() 等)然后运行 方法,它将使其静音,但如果我 运行 .py 完全它不会使其静音。有什么想法吗?

@jit
def annualize(data, freq=12, type='log'):

    T = data.shape[1]
    N = data.shape[0]
    rets = np.zeros([N,T-freq])
    for t in range(freq, T):
        valid = (data[:, t-freq] != 0.0) * (data[:, t] != 0.0)
        data0 = data[:, t-freq] * valid
        data1 = data[:, t] * valid
        if type == 'log':
            rets[:, t-freq] = np.log(data1) - np.log(data0)
        elif type == 'perc':
            rets[:, t-freq] = data1 / data0 - 1

    rets[np.where(np.isnan(rets))] = 0
    return rets

[... other code and classes ...]

 class MyClass:

   def __init__(self, args): 
       self.args = args
 
   def set_returns(self, freq = 'annual'):
       with warnings.catch_warnings():
            warnings.simplefilter('ignore', category=NumbaDeprecationWarning)
            warnings.simplefilter('ignore', category=NumbaPendingDeprecationWarning)
            if freq == 'annual':
                self.r = annualize(self.total_return.values, type='perc')
                self.log_r = annualize(self.total_return.values, type='log')
            elif freq == 'monthly':
                self.r = annualize(self.total_return.values, freq=1, type='perc')
                self.log_r = annualize(self.total_return.values, freq=1, type='log')

这样执行annualize()

>>> values = np.random.random((5, 24))
>>> values[3, 7] = np.nan
>>> annualize(values)

生成一长串消息,可以概括为以下错误:

 >>> zeros(list(int64)<iv=None>)
 No implementation of function Function(<intrinsic stub>) found for signature:    
 >>> stub(list(int64)<iv=None>)

这意味着您使用列表而不是元组调用 zeros()

更正此后,出现另一个错误(总结):

>>> setitem(array(float64, 2d, C), UniTuple(array(int64, 1d, C) x 2), Literal[int](0))
Rejected as the implementation raised a specific error:
   NotImplementedError: only one advanced index supported
rets[np.where(np.isnan(rets))] = 0

这意味着 Numba 只能在一维中使用高级索引。

任一错误都会导致 Numba 退回到标准 Python,相当于删除 @jit 装饰器。所以你的代码可以工作,但它根本不使用 Numba。

并且警告说您的代码将在未来的 Numba 版本中失败:

NumbaDeprecationWarning: 
Fall-back from the nopython compilation path to the object mode
compilation path has been detected, this is deprecated behaviour.

第二个问题(多维高级索引)只用一维就可以解决:

@nb.njit
def annualize2(data, freq=12, type='log'):

    N, T = data.shape
    ret_shape = (N, T - freq)
    rets = np.zeros(ret_shape)
    for t in range(freq, T):
        valid = (data[:, t - freq] != 0.0) * (data[:, t] != 0.0)
        data0 = data[:, t - freq] * valid
        data1 = data[:, t] * valid
        if type == 'log':
            rets[:, t - freq] = np.log(data1) - np.log(data0)
        elif type == 'perc':
            rets[:, t - freq] = data1 / data0 - 1

    rets = rets.ravel()
    rets[np.isnan(rets)] = 0
    return rets.reshape(ret_shape)

此版本不会产生错误或警告(Numba 会编译它)并产生与原始版本相同的结果。