numpy.ndarray 的类型提示/注释 (PEP 484)

Type hinting / annotation (PEP 484) for numpy.ndarray

有没有人为特定的 numpy.ndarray class 实现类型提示?

现在,我正在使用 typing.Any,但最好能有更具体的东西。

例如,如果 NumPy 人员添加 type alias for their array_like object class. Better yet, implement support at the dtype level, so that other objects would be supported, as well as ufunc

查看 DataShape。它使用数据类型以及一些语法来确定输入和输出数组的大小。

更新

检查最近的 numpy 版本以获得新的 typing 模块

https://numpy.org/doc/stable/reference/typing.html#module-numpy.typing

过时的回答

看起来 typing 模块开发于:

https://github.com/python/typing

numpy 存储库位于

https://github.com/numpy/numpy

Python 可以在

跟踪错误和提交

http://bugs.python.org/

添加功能的通常方法是分叉主存储库,开发功能直到它是 bomb proof,然后提交 pull request。显然,在流程的不同阶段,您需要其他开发人员的反馈。如果你不能自己做开发,那么你必须说服别人这是一个有价值的项目。

cython 有一种注释形式,它用于生成高效的 C 代码。


您引用了 numpy 文档中的 array-like 段落。注意它的 typing 信息:

A simple way to find out if the object can be converted to a numpy array using array() is simply to try it interactively and see if it works! (The Python Way).

换句话说,numpy 开发人员拒绝被压制。他们没有或不能用文字描述哪些对象可以或不能转换为 np.ndarray

In [586]: np.array({'test':1})   # a dictionary
Out[586]: array({'test': 1}, dtype=object)

In [587]: np.array(['one','two'])  # a list
Out[587]: 
array(['one', 'two'], 
      dtype='<U3')

In [589]: np.array({'one','two'})  # a set
Out[589]: array({'one', 'two'}, dtype=object)

对于您自己的函数,注释如

def foo(x: np.ndarray) -> np.ndarray:

有效。当然,如果你的函数最终调用了一些通过 asanyarray 传递参数的 numpy 函数(就像很多人所做的那样),这样的注释将是不完整的,因为你的输入可能是 list,或 np.matrix,等等


评价本问答时,注意日期。 484 当时是一个相对较新的 PEP,将其用于标准 Python 的代码仍在开发中。但看起来提供的链接仍然有效。

我所做的只是将其定义为

Dict[Tuple[int, int], TYPE]

例如,如果你想要一个浮点数数组,你可以这样做:

a = numpy.empty(shape=[2, 2], dtype=float) # type: Dict[Tuple[int, int], float]

从文档的角度来看,这当然不准确,但是对于分析正确的用法并使用 pyCharm 正确完成它非常有用!

nptyping 为指定 numpy 类型提示增加了很多灵活性。

我公司一直在使用:

from typing import TypeVar, Generic, Tuple, Union, Optional
import numpy as np

Shape = TypeVar("Shape")
DType = TypeVar("DType")

class Array(np.ndarray, Generic[Shape, DType]):
    """  
    Use this to type-annotate numpy arrays, e.g. 
        image: Array['H,W,3', np.uint8]
        xy_points: Array['N,2', float]
        nd_mask: Array['...', bool]
    """
    pass

def compute_l2_norm(arr: Array['N,2', float]) -> Array['N', float]:
    return (arr**2).sum(axis=1)**.5

print(compute_l2_norm(arr = np.array([(1, 2), (3, 1.5), (0, 5.5)])))

我们实际上有一个 MyPy 检查器来检查形状是否有效(我们应该在某个时候发布)。唯一的问题是它不会让 PyCharm 开心(即你仍然会收到讨厌的警告线):

Numpy 1.21 包含一个具有 NDArray 泛型的 numpy.typing 模块。


来自Numpy 1.21 docs
numpy.typing.NDArray = numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]

A generic version of np.ndarray[Any, np.dtype[+ScalarType]].

Can be used during runtime for typing arrays with a given dtype and unspecified shape.

Examples:

>>> import numpy as np
>>> import numpy.typing as npt

>>> print(npt.NDArray)
numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]

>>> print(npt.NDArray[np.float64])
numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

>>> NDArrayInt = npt.NDArray[np.int_]
>>> a: NDArrayInt = np.arange(10)

>>> def func(a: npt.ArrayLike) -> npt.NDArray[Any]:
...     return np.array(a)

截至 2021 年 11 月 10 日,根据 numpy/numpy#16544.

,对形状的支持仍在进行中