首頁 > 軟體

python程式設計學習np.float 被刪除的問題解析

2023-11-01 10:00:42

1. 概述

在Numpy 1.24版本中,刪除了像np.floatnp.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.float64np.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.intintnp.int32/np.int64
np.floatfloatnp.float32/np.float64
np.boolboolnp.bool_
np.complexcomplexnp.complex128
np.objectobject-
np.strstrnp.str_
np.longintnp.int32/np.int64
np.unicodestrnp.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

仔細看這段輸出的話,可以發現從 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.intnp.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萬行程式碼,我自己短期內就在兩個倉庫中遇到這個問題。好在解決辦法也比較直接,希望可以順利的過渡過去。

以上就是python程式設計學習np.float 被刪除的問題解析的詳細內容,更多關於python np.float 被刪除的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com