如何使用Numba创建并填充结构化数组,解决np.datetime64类型转换报错
Numba njit模式下创建结构化数组的解决方案
核心报错原因:Numba的nopython模式不支持直接将字符串传入np.datetime64()构造函数做类型转换,同时原生collections.namedtuple在njit下的类型识别也存在兼容问题。
修改后的可运行代码如下:
import numpy as np import numba # 提前定义结构化数组的dtype dtype_deals = [('DateTime', 'datetime64[s]'), ('Price', 'float64'), ('Quantity', 'uint64')] # Python层提前将日期字符串转成秒级整数时间戳,避开njit的字符串转日期限制 deal_raw = [ (np.datetime64('2015-02-27T15:12:12', 's').astype(np.int64), 12.48, 10), (np.datetime64('2015-03-17T15:08:36', 's').astype(np.int64), 1.15, 100), (np.datetime64('2015-04-02T15:14:32', 's').astype(np.int64), 11.01, 20) ] @numba.njit def my_func(): # 预先分配指定长度的结构化数组,适配njit类型识别 deals = np.empty(len(deal_raw), dtype=dtype_deals) for idx, (ts, price, qty) in enumerate(deal_raw): # 整数转datetime64[s]是njit支持的操作 deals[idx]['DateTime'] = np.datetime64(ts, 's') deals[idx]['Price'] = price deals[idx]['Quantity'] = qty return deals print(str(my_func()))
核心修改点:
- 把所有字符串转日期的逻辑移到njit函数外的Python层执行,转成秒级整数时间戳后再传入njit内部,避开Numba不支持的字符串转datetime64操作
- 弃用
collections.namedtuple,直接操作结构化数组的字段赋值,避免njit的类型识别错误 - 用
np.empty预先分配固定长度的结构化数组,相比list append后转数组的方式,兼容性更好、运行效率更高,也符合Numba nopython模式的类型要求
如果需要在njit内部动态生成日期,直接用整数运算生成对应秒级时间戳,再转成datetime64即可,全程不要传入字符串做日期转换。
内容的提问来源于stack exchange,提问作者AlekseyPython
相关产品推荐
相关产品推荐

