0

0

Numba njit 函数中 np.array() 构造器的误区与解决方案

碧海醫心

碧海醫心

发布时间:2025-10-14 13:33:31

|

252人浏览过

|

来源于php中文网

原创

Numba njit 函数中 np.array() 构造器的误区与解决方案

在numba jit编译函数中,直接使用`np.array(existing_numpy_array)`构造新数组会引发`typingerror`,因为numba的`np.array`实现不支持以现有numpy数组作为其唯一参数来重新创建数组。该问题与numba字典无关,而是numpy数组构造方式的限制。解决方案是使用解包操作符,如`np.array([*existing_numpy_array])`,以正确传递数组元素。

在高性能计算领域,Numba通过即时编译(JIT)技术显著提升Python代码,特别是涉及NumPy数组操作时的执行效率。然而,在使用Numba的@njit装饰器时,开发者可能会遇到一些与NumPy数组构造相关的细微差别,这些差别可能导致TypingError。本文将深入探讨一个常见的误区:在Numba JIT编译环境中,如何正确地从一个现有NumPy数组创建另一个NumPy数组,以及避免由此产生的TypingError。

理解Numba中np.array()构造器的行为

当我们在Numba JIT编译的函数中操作NumPy数组时,需要特别注意np.array()构造函数的行为。一个常见的误解是,可以像在纯Python/NumPy环境中那样,直接将一个现有的NumPy数组作为参数传递给np.array()来创建一个新的数组。例如,以下代码在纯Python环境中通常是可行的:

import numpy as np
a = np.array([1, 2, 3])
b = np.array(a) # b是a的一个副本

然而,在Numba的@njit编译模式下,这种做法会引发TypingError。

示例:导致TypingError的代码

考虑以下Numba JIT编译函数中的代码片段:

import numpy as np
import numba as nb

@nb.njit
def create_array_from_existing(arr_in):
    # 尝试直接从现有NumPy数组arr_in创建新数组
    new_arr = np.array(arr_in)
    return new_arr

# 调用函数
a = np.array([1, 2])
# create_array_from_existing(a) # 这行代码将导致TypingError

执行上述代码,Numba会抛出类似于以下的TypingError:

TypingError: No implementation of function Function() found for signature:
>>> array(array(int64, 1d, C))

错误信息清晰地指出,Numba无法找到一个np.array()的实现,其签名接受一个array(int64, 1d, C)类型的参数。这意味着Numba的np.array()构造器在njit模式下,并不支持直接以一个NumPy数组对象作为其唯一的输入参数来重新创建数组。它期望的输入通常是一个Python序列(如列表、元组)或可迭代对象,其中包含可以转换为数组元素的标量值。

进一步的错误信息可能会显示:array(int64, 1d, C) not allowed in a homogeneous sequence。这表明Numba试图将整个NumPy数组对象arr_in视为一个序列中的单个元素,而不是将其内部元素提取出来构成新数组。

Kive
Kive

一站式AI图像生成和管理平台

下载

解决方案:使用解包操作符

为了在Numba JIT编译函数中正确地从一个现有NumPy数组的元素创建新数组,我们需要明确地将原数组的元素解包(unpack)到一个Python序列中,然后将该序列传递给np.array()。Python的解包操作符*在这里发挥了关键作用。

import numpy as np
import numba as nb

@nb.njit
def create_array_from_existing_fixed(arr_in):
    # 使用解包操作符将arr_in的元素传递给np.array()
    new_arr = np.array([*arr_in])
    return new_arr

# 调用函数
a = np.array([1, 2])
result = create_array_from_existing_fixed(a)
print(result)
print(type(result))

输出:

[1 2]

通过np.array([*arr_in]),我们将arr_in中的所有元素解包到一个临时的Python列表中,然后np.array()能够正确地从这个列表构造一个新的NumPy数组。这种方法符合Numba对np.array()构造器参数类型的期望。

注意事项与最佳实践

  1. 区分复制与重新创建:

    • 如果你仅仅需要一个现有NumPy数组的副本,最直接且推荐的方法是使用arr_in.copy()。这通常更高效,并且明确表达了意图。
      @nb.njit
      def copy_array(arr_in):
      return arr_in.copy()
    • np.array([*arr_in])实际上创建了一个新的数组,其元素与原数组相同。如果需要更改数据类型或数组布局,这种方法结合dtype参数会很有用。
  2. Numba字典与NumPy数组值: 最初的问题中提到NumPy数组作为字典值。实际上,Numba字典可以很好地存储NumPy数组作为其值,只要这些数组的类型在编译时是同质的(homogeneous)。本例中的TypingError与字典本身无关,而是np.array()构造函数的特定行为导致的。一旦NumPy数组被正确创建,将其赋值给Numba字典的值是完全支持的。

    @nb.njit
    def foo_with_dict(a):
        d = nb.typed.Dict.empty(
            key_type=nb.types.int64,
            value_type=nb.typeof(np.array([0])) # 定义字典值的类型
        )
        d[1] = np.array([*a]) # 正确创建并赋值
        return d
    
    a = np.array([1, 2])
    my_dict = foo_with_dict(a)
    print(my_dict)
  3. 理解Numba的类型推断: Numba在编译时会进行严格的类型推断。当遇到np.array(arr_in)时,它推断arr_in是一个NumPy数组类型,并尝试寻找一个接受NumPy数组作为参数的np.array重载。由于Numba没有这样的直接重载来“复制”一个数组,因此会报错。而[*arr_in]会产生一个临时的Python列表,Numba能够识别并处理np.array(list_of_scalars)的签名。

总结

在Numba的@njit编译环境中,直接使用np.array(existing_numpy_array)来创建新数组会导致TypingError。核心原因在于Numba对np.array()构造器参数类型的严格要求,它不直接支持以一个完整的NumPy数组对象作为输入来重新创建数组。正确的做法是利用Python的解包操作符*,将现有NumPy数组的元素解包成一个列表,然后将该列表传递给np.array(),即np.array([*existing_numpy_array])。此外,如果仅仅需要数组的副本,使用existing_numpy_array.copy()是更简洁高效的选择。理解这些细节对于在Numba中编写高效且无误的NumPy代码至关重要。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

769

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

661

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

764

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

659

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1345

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

549

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

579

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

730

2023.08.11

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

38

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 10.2万人学习

Django 教程
Django 教程

共28课时 | 3.3万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号