如何为Numba @guvectorize指定datetime dtype?遇nb未定义报错求解
报错根因
触发你当前看到的NameError: name 'nb' is not defined的核心原因是:@guvectorize 传入的字符串格式签名,内部会通过独立的eval流程解析,这个解析流程的全局命名空间仅加载Numba内置类型的字典,不会注入你当前代码里定义的nb别名,所以字符串里写nb.types.NPDatetime(...)会直接被识别为未定义变量。
顺着代码逻辑往后排查,即使把这个NameError解决了,原示例还有两个会阻碍运行的问题:
- 示例代码缺失必要导入:用到了
np、pd但没有显式导入numpy和pandas - 函数体里的
np.ndenumerate不属于Numba可编译支持的接口,会直接触发编译报错
可直接运行的修正版本
import numpy as np import pandas as pd import numba as nb from numba import guvectorize # 修正1:去掉签名字符串里的nb.前缀,使用Numba解析时可直接识别的类型名 # 如不想用字符串解析,也可以直接传类型元组构造签名,完全规避解析隔离问题: # @guvectorize((nb.void(nb.types.NPDatetime("ns")[:], nb.types.NPDatetime("ns")[:]),), '(m)->(m)') @guvectorize('void(NPDatetime("ns")[:], NPDatetime("ns")[:])', '(m)->(m)') def ts_copy(ts, ts_c): # 修正2:替换Numba不支持的np.ndenumerate为基础索引循环 for i in range(ts.shape[0]): ts_c[i] = ts[i] ts = pd.date_range(start='2021/1/1 08:00', end='2021/1/1 18:00', freq='1H').to_numpy() ts_c = np.empty(ts.size, dtype='datetime64[ns]') res = ts_copy(ts, ts_c) print(res)
实操注意事项
- 写字符串格式的Numba编译签名时,不要引用当前Python作用域的自定义变量,签名的解析上下文和业务代码的作用域是完全隔离的。如果需要自定义类型,直接传入构造好的Numba类型对象组成元组作为签名参数,比写字符串的可控性高很多。
- Numba对datetime64类型的支持仅覆盖纳秒精度场景,对应类型为
NPDatetime('ns'),其他精度的datetime类型目前暂不支持直接编译。 - 写Numba函数体时尽量使用基础循环、原生语法,不要随意引入未被Numba实现的numpy高阶方法,避免编译失败。
内容的提问来源于stack exchange,提问作者pierre_j
相关产品推荐
相关产品推荐

