1. 概述
在Numpy 1.24版别中,删去了像np.float
、np.int
这样的 Python 内置类型的 alias,因此今后在代码中运用这些类型会报错AttributeError: module 'numpy' has no attribute 'float'
, 触及的类型包括:
numpy.bool
numpy.int
numpy.float
numpy.complex
numpy.object
numpy.str
numpy.long
numpy.unicode
那该怎么处理这个过错呢?
TL;DR
- 对于在标量上的操作,直接运用Python内置类型替换
foo = np.random.rand(10)
# 原先用法,注意foo[0]是一个标量
bar = np.float(foo[0])
# 新用法
bar = float(foo[0])
- 对于在
np.ndarray
上的操作,运用np.float64
或np.float32
来代替,具体选择哪个需求自己根据状况来确定,不同类型精度会有不同,下面举两个比如:
# 原先用法
foo = np.random.rand(10, dtype=np.float)
# 新用法
foo = np.random.rand(10, dtype=np.float32)
# 原先用法
foo = np.random.rand(10).astype(np.float)
# 新用法
foo = np.random.rand(10).astype(np.float32)
这儿列出来了删去类型在标量和np.ndarray
上的代替,便利查找
原先类型 | 标量替换类型 |
np.ndarray 替换类型 |
---|---|---|
np.int | int | np.int32/np.int64 |
np.float | float | np.float32/np.float64 |
np.bool | bool | np.bool_ |
np.complex | complex | np.complex128 |
np.object | object | – |
np.str | str | np.str_ |
np.long | int | np.int32/np.int64 |
np.unicode | str | np.str_ |
具体阐明参阅NumPy 1.20.0 Release Notes。
下面具体说说事情的来龙去脉。
2. 代码验证
下面我搭建 Numpy 1.20.0 和 1.24.0 的环境进行简略测试,以及剖析为什么会弃用这些类型。
首先是 Numpy 1.20.0 环境搭建与简略测试:
python -m venv np1.20
source np1.20/bin/activate
pip install numpy==1.20
python -c "import numpy as np; a = np.array([1.0], dtype=np.float)"
输出如下:
<string>:1: DeprecationWarning: `np.float` is a deprecated alias for the builtin `float`. To silence this warning, use `float` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.float64` here.
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
仔细看这段输出的话,能够发现从 Numpy 1.20 版别开端,Numpy现已弃用np.float
类型了,并且给出了替换建议,以及具体的阐明文档地址。
而在 Numpy 1.24版别里面,正式删去了np.float
,能够用下面的代码来测试。
首先我们创立一个新的环境,装置Numpy 1.24版别,然后创立一个np.float
类型的数组:
python -m venv np1.24
source np1.24/bin/activate
pip install numpy==1.24
python -c "import numpy as np; a = np.array([1.0], dtype=np.float)"
输出如下:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/name/np1.24/lib/python3.9/site-packages/numpy/__init__.py", line 284, in __getattr__
raise AttributeError("module {!r} has no attribute "
AttributeError: module 'numpy' has no attribute 'float'
直接就报了我们开头提到的属性过错。
3. Why
其实早在2015年,Numpy 开发者就在策划删去这些类型了,只不过当时运用范围太广,删去造成的影响太大,所以在近8年,1.20-1.24 4个版别的Warning后,才正式删去。
为什么要删去这些操作呢?我自己觉得是因为np.float
这种类型太容易误用了。大家都以为np.float
是一个Numpy的数据类型,是np.float32
的alias,但实践它是内置类型,是int
类型的alias。
就像下面这个比如:
>>> foo = np.array([10], dtype=np.int32)
>>> bar = np.int(foo)
>>> type(bar)
<class 'int'>
>>> baz = np.int32(foo)
>>> type(baz)
<class 'numpy.ndarray'>
能够看到,对np.ndarray
数组进行np.int
和np.int32
的操作,一个得到int
类型的变量,另一个得到的是np.ndarray
类型的变量。
具体的原因能够参阅上面的 issue 链接。
那最早为什么还要引进np.float
呢?直接用Python内置的类型不好吗?其实这是在很早的Numpy版别中过错地引进的,那个版别np.float
的含义便是np.float64
,只不过后来版别中np.float
的含义修改了,但假如直接删去np.float
,有人运用老版别的Numpy,就会在履行from numpy import *
报错。当时那个老版别现已很少有人用了 ,所以就删去了。
4. 带来的影响
这个改动带来的影响能够说是非常大了,简略来说,在 Numpy 1.24.0以上的版别中,运用np.float
的代码都会直接报错。而 Numpy 作为 Python 在科学计算中的基础包,被广泛运用的程度无需我赘述。
简略在GitHub 搜索了一下,光触及到np.float
的(成果1, 成果2)就有近9万行代码,我自己短期内就在两个仓库中遇到这个问题。好在处理办法也比较直接,期望能够顺畅的过渡过去。