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 的具体信息 什么是List
。 list
小写是一个普通的 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
文件。
我已经安装了mypy
和data-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 检查器,它实际上检查形状是否有效(我们应该在某个时候发布)。
唯一的问题是它不会让 PyCharm 高兴(即你仍然会收到讨厌的警告行):
【讨论】:
我很高兴听到这个消息!!!请尽快释放检查器!:) 或者存根文件之类的。以上是关于NumPy ndarray dtype 的类型提示?的主要内容,如果未能解决你的问题,请参考以下文章