【问题标题】:Type hint for NumPy ndarray dtype?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

标签: python python-3.x numpy type-hinting python-typing


【解决方案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 #7370numpy-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 高兴(即你仍然会收到讨厌的警告行):

    【讨论】:

    • 我很高兴听到这个消息!!!请尽快释放检查器!:) 或者存根文件之类的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2023-03-19
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多