NumPy ndarray dtype 的类型提示?

Posted

技术标签:

【中文标题】NumPy ndarray dtype 的类型提示?【英文标题】:Type hint for NumPy ndarray dtype? 【发布时间】:2019-06-27 11:23:44 【问题描述】:

我想要一个函数在其 dtype 旁边包含 NumPy ndarray 的类型提示。

例如,使用列表,可以执行以下操作...

def foo(bar: List[int]):
   ...

...为了给出bar 必须是由int 组成的list 的类型提示。

不幸的是,这种语法会为 NumPy ndarray 抛出异常:

def foo(bar: np.ndarray[np.bool]):
   ...

> np.ndarray[np.bool]) (...) TypeError: 'type' object is not subscriptable

是否可以为np.ndarray 提供dtype 特定的类型提示?

【问题讨论】:

上次我回答了一个类型提示问题,我找不到太多 numpy 的具体信息 什么是Listlist 小写是一个普通的 Python 函数/类型。 提供更完整的上下文 - 你在导入什么 typing?你是如何使用打字的?您找到并导入了哪些numpy 特定类型? @hpaulj, List 是内置的 mypy 类型:mypy.readthedocs.io/en/stable/builtin_types.html#built-in-types 【参考方案1】:

您可以查看nptyping:

from nptyping import NDArray, Bool

def foo(bar: NDArray[Bool]):
   ...

或者您可以只使用字符串作为类型提示:

def foo(bar: 'np.ndarray[np.bool]'):
   ...

【讨论】:

使用字符串类型提示有什么作用?只是显示为文档?或者编辑器可以真正解析它们并执行它们吗? 它用作文档,实际上并没有做太多事情(除非您出于某种原因开始使用检查来解析它们)。一些编辑器(例如 PyCharm)足够聪明,可以查看它们是否能够理解文本类型提示。有时您别无选择,只能使用文本类型提示。例如,当提示方法的参数与持有该方法的类的类型相同时。 请注意,从 1.20 开始,它现在可以在 numpy.typing.NDArray 访问,而不是外部包:numpy.org/devdocs/reference/typing.html【参考方案2】:

查看data-science-types 包。

pip install data-science-types

MyPy 现在可以访问 Numpy、Pandas 和 Matplotlib 存根。 允许以下场景:

# program.py

import numpy as np
import pandas as pd

arr1: np.ndarray[np.int64] = np.array([3, 7, 39, -3])  # OK
arr2: np.ndarray[np.int32] = np.array([3, 7, 39, -3])  # Type error

df: pd.DataFrame = pd.DataFrame('col1': [1,2,3], 'col2': [4,5,6]) # OK
df1: pd.DataFrame = pd.Series([1,2,3]) # error: Incompatible types in assignment (expression has type "Series[int]", variable has type "DataFrame")

像平常一样使用 mypy。

$ mypy program.py

与函数参数一起使用

def f(df: pd.DataFrame):
    return df.head()

if __name__ == "__main__":
    x = pd.DataFrame('col1': [1, 2, 3, 4, 5, 6])
    print(f(x))

$ mypy program.py
> Success: no issues found in 1 source file

【讨论】:

是的,谢谢你的提问,我测试了确定。将以示例扩展答案。 当执行使用这个库的脚本时,我仍然得到 TypeError: 'type' object is not subscriptable。所以,PyCharm 不再给出类型警告了,但是执行的时候会报错。 你是为 pd.DataFrame 还是为 Numpy 获得这个?我以前得到过这个,但我忘记了我是如何复制它的。我也没有在 PyCharm 中,这只是使用 JupyterLab 的终端运行.py 文件。 我已经安装了mypydata-science-types,当我尝试这个例子时,我得到了error: "ndarray" expects no type arguments, but 1 given。有什么解决办法吗?我发现了关于从 repo 安装 mypy 的东西,但它似乎不起作用。 来自 data-science-types github: ⚠️ 这个项目大部分已经停止开发 ⚠️ pandas 团队和 numpy 团队都在将类型存根集成到他们的代码库中,我们没有看到与他们竞争的重点。【参考方案3】:

据我所知,尚无法在函数签名中的 numpy 数组类型提示中指定 dtype。计划在未来的某个时间点实施。有关当前开发状态​​的更多详细信息,请参阅numpy GitHub issue #7370 和numpy-stubs GitHub。

【讨论】:

【参考方案4】:

类型文档的一种非正式解决方案如下:

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.

        def transform_image(image: Array['H,W,3', np.uint8], ...):
            ...

    """
    pass


def func(arr: Array['N,2', int]):
    return arr*2


print(func(arr = np.array([(1, 2), (3, 4)])))

我们一直在我的公司使用它,并制作了一个 MyPy 检查器,它实际上检查形状是否有效(我们应该在某个时候发布)。

唯一的问题是它不会让 PyC​​harm 高兴(即你仍然会收到讨厌的警告行):

【讨论】:

我很高兴听到这个消息!!!请尽快释放检查器!:) 或者存根文件之类的。

以上是关于NumPy ndarray dtype 的类型提示?的主要内容,如果未能解决你的问题,请参考以下文章

NumPy Ndarray对象

NumPy库

# numpy 数据分析基础

Numpy:ndarray数据类型和运算

Numpy(上)

numpy 基础