NumPy 1.21.0 發行說明#

NumPy 1.21.0 版本發行的重點如下:

  • 持續的 SIMD 工作,涵蓋更多函數和平台,

  • 關於新的 dtype 基礎架構和轉換的初步工作,

  • 適用於 Mac 上 Python 3.8 和 Python 3.9 的 universal2 wheels,

  • 改進的文件,

  • 改進的註釋,

  • 用於隨機數的新 PCG64DXSM 位元產生器。

此外,還有大量常見的錯誤修正和其他改進。

此版本支援的 Python 版本為 3.7-3.9。Python 3.10 的官方支援將在發佈時加入。

警告

使用 gcc-11.1 編譯 NumPy 1.20.0 時,存在未解決的問題。

  • 最佳化等級 -O3 在執行測試時會產生許多不正確的警告。

  • 在某些硬體上,NumPy 會在無限迴圈中卡住。

新函數#

新增 PCG64DXSM BitGenerator#

在大量平行環境中使用 PCG64 BitGenerator 已被證明存在統計上的弱點,這在 numpy 1.17 的首次發行時並不明顯。大多數使用者永遠不會觀察到這種弱點,並且可以安全地繼續使用 PCG64。我們引入了一個新的 PCG64DXSM BitGenerator,它最終將成為未來版本中 default_rng 使用的新預設 BitGenerator 實作。PCG64DXSM 在保留 PCG64 的效能和特性的同時,解決了統計上的弱點。

詳情請參閱 使用 PCG64DXSM 升級 PCG64

(gh-18906)

已過期的棄用#

  • shape 參數 unravel_index 不能再作為 dims 關鍵字參數傳遞。(已在 NumPy 1.16 中棄用。)

    (gh-17900)

  • 函數 PyUFunc_GenericFunction 已停用。它已在 NumPy 1.19 中棄用。使用者應使用 Python API 直接呼叫 ufunc。

    (gh-18697)

  • 函數 PyUFunc_SetUsesArraysAsData 已停用。它已在 NumPy 1.19 中棄用。

    (gh-18697)

  • 類別 PolyBase 已移除(已在 numpy 1.9.0 中棄用)。請改用抽象 ABCPolyBase 類別。

    (gh-18963)

  • 未使用的 PolyErrorPolyDomainError 例外已移除。

    (gh-18963)

棄用#

.dtype 屬性必須傳回 dtype#

如果傳遞到 np.dtype 或作為 dtype=obj 參數的物件的 .dtype 屬性不是 dtype,現在會發出 DeprecationWarning。NumPy 將停止嘗試遞迴地強制轉換 .dtype 的結果。

(gh-13578)

numpy.convolvenumpy.correlate 的不精確匹配已棄用#

當在函數的 mode 參數中找到不區分大小寫和/或不精確的匹配時,convolvecorrelate 現在會發出警告。對於 mode 參數,請傳遞完整的 "same""valid""full" 字串,而不是 "s""v""f"

(gh-17492)

np.typeDict 已正式棄用#

np.typeDictnp.sctypeDict 的已棄用別名,並且已經超過 14 年了(6689502)。每當取得 np.typeDict 時,現在都會發出棄用警告。

(gh-17586)

在類似陣列的建立期間將引發例外#

當物件在存取特殊屬性 __array____array_interface__ 期間引發例外時,此例外通常會被忽略。現在,當例外不是 AttributeError 時,會發出警告。若要消除警告,必須調整引發例外的類型以引發 AttributeError

(gh-19001)

四個 ndarray.ctypes 方法已棄用#

ndarray.ctypes 物件的四個方法已棄用,因為它們是各自屬性的(未記載)實作產物。

有問題的方法是

  • _ctypes.get_data(請改用 _ctypes.data

  • _ctypes.get_shape(請改用 _ctypes.shape

  • _ctypes.get_strides(請改用 _ctypes.strides

  • _ctypes.get_as_parameter(請改用 _ctypes._as_parameter_

(gh-19031)

已過期的棄用#

  • shape 參數 numpy.unravel_index 不能再作為 dims 關鍵字參數傳遞。(已在 NumPy 1.16 中棄用。)

    (gh-17900)

  • 函數 PyUFunc_GenericFunction 已停用。它已在 NumPy 1.19 中棄用。使用者應使用 Python API 直接呼叫 ufunc。

    (gh-18697)

  • 函數 PyUFunc_SetUsesArraysAsData 已停用。它已在 NumPy 1.19 中棄用。

    (gh-18697)

移除已棄用的 PolyBase 和未使用的 PolyErrorPolyDomainError#

類別 PolyBase 已移除(已在 numpy 1.9.0 中棄用)。請改用抽象 ABCPolyBase 類別。

此外,未使用的 PolyErrorPolyDomainError 例外已從 numpy.polynomial 中移除。

(gh-18963)

相容性注意事項#

通用函數中的錯誤類型變更#

通用函數現在在某些情況下可能會針對無效輸入引發不同的錯誤。主要變更應為 RuntimeError 已被更合適的 TypeError 取代。當同一個呼叫中存在多個錯誤時,NumPy 現在可能會引發不同的錯誤。

(gh-15271)

__array_ufunc__ 參數驗證#

NumPy 現在將在呼叫 __array_ufunc__ 之前部分驗證參數。先前,當已知會發生分派時,有可能傳遞無效參數(例如不存在的關鍵字參數)。

(gh-15271)

__array_ufunc__ 和額外的位置引數#

先前,所有以位置傳遞的參數都會檢查 __array_ufunc__ 支援。在 reduceaccumulatereduceat 的情況下,所有參數都可以按位置傳遞。這表示當它們按位置傳遞時,先前可能會要求它們透過 __array_ufunc__ 處理 ufunc 呼叫。由於這取決於參數的傳遞方式(按位置或按關鍵字),NumPy 現在只會分派輸入和輸出陣列。例如,NumPy 永遠不會在縮減中分派 where 陣列,例如 np.add.reduce

(gh-15271)

驗證 Generator.uniform 中的輸入值#

np.random.Generator.uniform 中檢查 high - low >= 0。如果 low > high,則引發 ValueError。先前接受了順序錯誤的輸入並靜默交換,因此如果 low > high,則產生的值為 high + (low - high) * random()

(gh-17921)

/usr/include 從預設包含路徑中移除#

使用 numpy.distutils 建置套件時,預設包含路徑不再包含 /usr/include。此路徑通常由編譯器新增,硬式編碼它可能會產生問題。如果這導致問題,請開啟 issue。PR 18658 中記載了一個解決方法。

(gh-18658)

dtype=... 比較的變更#

當比較 ufunc(equalless 等)的 dtype= (或 signature)參數被使用時,這將表示未來所需的輸出 dtype。這表示

np.equal(2, 3, dtype=object)

將給出 FutureWarning,表示它將在未來傳回 object 陣列,目前對於

np.equal(None, None, dtype=object)

由於 np.array(None) 已經是物件陣列,因此會發生這種情況。(這也會發生在其他一些 dtype 上。)

由於比較通常只傳回布林陣列,因此提供任何其他 dtype 在未來總是會引發錯誤,並且現在會發出 DeprecationWarning

(gh-18718)

ufunc 中 dtypesignature 參數的變更#

通用函數參數 dtypesignature 也適用於縮減,例如 np.add.reduce(這是 np.sum 的實作),當提供的 dtype 不是「基本」dtype 時,現在會發出警告。

NumPy 幾乎總是忽略這些輸入上的元資料、位元組順序或時間單位。NumPy 現在將始終忽略它,並且如果位元組順序或時間單位已變更,則會引發錯誤。以下是最重要的變更範例,這些變更將會引發錯誤。在某些情況下,先前儲存的資訊未被忽略,在所有這些情況下,現在都會引發錯誤

# Previously ignored the byte-order (affect if non-native)
np.add(3, 5, dtype=">i32")

# The biggest impact is for timedelta or datetimes:
arr = np.arange(10, dtype="m8[s]")
# The examples always ignored the time unit "ns":
np.add(arr, arr, dtype="m8[ns]")
np.maximum.reduce(arr, dtype="m8[ns]")

# The following previously did use "ns" (as opposed to `arr.dtype`)
np.add(3, 5, dtype="m8[ns]")  # Now return generic time units
np.maximum(arr, arr, dtype="m8[ns]")  # Now returns "s" (from `arr`)

這同樣適用於內部使用這些函數的函數,例如 np.sum。此變更是為了在 NumPy 內實現一致的處理方式所必需的。

如果您遇到這些問題,在大多數情況下,請傳遞例如 dtype=np.timedelta64,這清楚地表示一個通用的 timedelta64,而沒有定義任何單位或位元組順序。如果您需要精確指定輸出 dtype,您可以透過強制轉換輸入或使用 out= 提供輸出陣列來實現。

NumPy 可能會選擇在未來允許在此處提供精確的輸出 dtype,這將以 FutureWarning 作為前導。

(gh-18718)

Ufunc signature=...dtype= 通用化和 casting#

由於促銷方面的變更,與 1.20 相比,np.ufunc(1.0, 1.0, signature=...)np.ufunc(1.0, 1.0, dtype=...) 的行為現在可能會在 1.21 中產生不同的迴圈。當先前使用 signature 時,輸入的轉換檢查會放寬,這可能會導致不安全地向下轉換輸入,尤其是與 casting="unsafe" 結合使用時。

現在保證轉換是安全的。如果僅部分提供簽名,例如使用 signature=("float64", None, None),則可能會導致找不到迴圈(錯誤)。在這種情況下,必須提供完整的簽名以強制轉換輸入。如果使用 dtype="float64" 或僅設定輸出(例如 signature=(None, None, "float64"),則不會變更。我們預期受此變更影響的使用者非常少。

此外,dtype="float64" 的含義已略作修改,現在嚴格強制僅正確的輸出(而非輸入)DType。這表示它現在始終等效於

signature=(None, None, "float64")

(如果 ufunc 有兩個輸入和一個輸出)。由於這可能會導致在某些情況下找不到迴圈,NumPy 通常也會搜尋迴圈

signature=("float64", "float64", "float64")

如果第一次搜尋失敗。在未來,此行為可能會被自訂,以針對更複雜的 ufunc 實現預期的結果。(對於某些通用函數,例如 np.ldexp,輸入可以具有不同的 DType。)

(gh-18880)

Distutils 強制 clang 上使用嚴格的浮點模型#

當使用 clang 編譯時,NumPy distutils 現在將始終新增 -ffp-exception-behavior=strict 編譯器旗標。Clang 預設為非嚴格版本,這允許編譯器產生無法正確設定浮點警告/錯誤的程式碼。

(gh-19049)

C API 變更#

使用 ufunc->type_resolver 和「類型元組」#

NumPy 現在在呼叫類型解析器函數之前,會將「類型元組」參數正規化。請注意,使用此類型解析器是舊版行為,NumPy 在可能的情況下不會這樣做。強烈建議不要呼叫 ufunc->type_resolverPyUFunc_DefaultTypeResolver,如果這樣做,現在將強制執行正規化的類型元組。請注意,這不會影響提供類型解析器,預期類型解析器在大多數情況下會繼續運作。如果您有呼叫類型解析器的意外用例,請通知 NumPy 開發人員,以便找到解決方案。

(gh-18718)

新功能#

新增了 mypy 外掛程式,用於處理平台特定的 numpy.number 精度#

現在有一個 mypy 外掛程式可用於自動分配某些 number 子類別的(平台相關)精度,包括 int_intplonglong 等。有關受影響類別的全面概述,請參閱關於 純量類型 的文件。

請注意,雖然外掛程式的使用完全是可選的,但如果沒有它,上述類別的精度將被推斷為 Any

若要啟用外掛程式,必須將其新增到 mypy 組態檔

[mypy]
plugins = numpy.typing.mypy_plugin

(gh-17843)

讓 mypy 外掛程式管理擴充精度 numpy.number 子類別#

mypy 外掛程式,在 numpy/numpy#17843 中引入,已擴充:外掛程式現在會移除平台特定擴充精度類型的註釋,這些類型在相關平台上不可用。例如,當 float128 不可用時,它將移除 float128

如果沒有外掛程式,就 mypy 而言,所有 擴充精度類型都將在所有平台上可用。

若要啟用外掛程式,必須將其新增到 mypy 組態檔

[mypy]
plugins = numpy.typing.mypy_plugin

(gh-18322)

用於列印浮點值的新 min_digits 參數#

一個新的 min_digits 參數已新增到 dragon4 浮點列印函數 format_float_positionalformat_float_scientific。此 kwd 保證在 unique=True 模式下列印時,至少會列印給定位數的數字,即使額外的數字對於唯一指定值是不必要的。它是 precision 參數的對應項,precision 參數設定要列印的最大位數。當固定精度模式下的 unique=False 時,它沒有任何作用,並且 precision 參數會固定位數。

(gh-18629)

f2py 現在可以識別 Fortran 抽象介面區塊#

f2py 現在可以解析抽象介面區塊。

(gh-18695)

透過環境變數設定 BLAS 和 LAPACK#

可以使用 NPY_BLAS_LIBSNPY_LAPACK_LIBS 環境變數繞過已安裝 BLAS 和 LAPACK 程式庫的自動偵測。相反地,將直接使用這些環境變數中的連結旗標,並且語言假定為 F77。這在自動化建置中特別有用,在自動化建置中,已知已安裝的 BLAS 和 LAPACK 程式庫完全相同。一個用例是透過 stub 程式庫連結在執行階段替換實際實作。

如果設定了 NPY_CBLAS_LIBS(除了 NPY_BLAS_LIBS 之外是可選的),這也將被使用,方法是定義 HAVE_CBLAS 並將環境變數內容附加到連結旗標。

(gh-18737)

已為 ndarray 新增執行階段可下標的別名#

已新增 numpy.typing.NDArray,它是 np.ndarray[Any, np.dtype[~Scalar]] 的執行階段可下標別名。新的類型別名可用於註釋具有給定 dtype 和未指定形狀的陣列。1

1 截至 1.21,NumPy 不支援註釋陣列形狀,但預計未來會變更(請參閱 PEP 646)。

範例#

>>> import numpy as np
>>> import numpy.typing as npt

>>> print(npt.NDArray)
numpy.ndarray[typing.Any, numpy.dtype[~ScalarType]]

>>> print(npt.NDArray[np.float64])
numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

>>> NDArrayInt = npt.NDArray[np.int_]
>>> a: NDArrayInt = np.arange(10)

>>> def func(a: npt.ArrayLike) -> npt.NDArray[Any]:
...     return np.array(a)

(gh-18935)

改進#

numpy.unwrap 的任意 period 選項#

相位展開的區間大小不再限於 2 * pi。這對於展開角度特別有用,但也可用於其他區間。

>>> phase_deg = np.mod(np.linspace(0,720,19), 360) - 180
>>> phase_deg
array([-180., -140., -100.,  -60.,  -20.,   20.,   60.,  100.,  140.,
       -180., -140., -100.,  -60.,  -20.,   20.,   60.,  100.,  140.,
       -180.])

>>> unwrap(phase_deg, period=360)
array([-180., -140., -100.,  -60.,  -20.,   20.,   60.,  100.,  140.,
        180.,  220.,  260.,  300.,  340.,  380.,  420.,  460.,  500.,
        540.])

(gh-16987)

np.unique 現在返回單個 NaN#

np.unique 作用於包含多個 NaN 條目的陣列時,其返回值會為原始陣列中每個 NaN 條目包含一個 NaN。現在已改進為返回的陣列僅包含一個 NaN 作為最後一個元素。

此外,對於複數陣列,所有 NaN 值都被視為等效(無論 NaN 在實部還是虛部)。作為返回陣列的代表,會選擇詞典編纂順序中最小的一個 - 請參閱 np.sort 以了解複數陣列的詞典編纂順序是如何定義的。

(gh-18070)

Generator.rayleighGenerator.geometric 效能已提升#

Generator 中 Rayleigh 和 geometric 隨機變數生成的效能已提升。這些都是指數隨機變數的轉換,而基於對數的慢速逆累積分布函數轉換已被基於 Ziggurat 的指數變數生成器取代。

此變更會中斷從這些分佈中產生變數時的變數流。

(gh-18666)

佔位符註解已改進#

所有先前註解為 typing.Any 的佔位符註解都已改進。在適當的地方,它們已被替換為顯式函數定義、類別或其他雜項物件。

(gh-18934)

效能提升#

NumPy 陣列的整數除法效能提升#

當除數為常數時,NumPy 陣列的整數除法現在使用 libdivide。透過使用 libdivide 和其他次要最佳化,速度大幅提升。// 運算符和 np.floor_divide 都使用了新的變更。

(gh-17727)

提升小型陣列的 np.savenp.load 效能#

對於小型陣列,np.save 現在快很多。

對於小型陣列,np.load 也更快,但僅限於使用版本 >= (3, 0) 序列化時。

這兩者都是透過移除僅與 Python 2 相關的檢查來完成的,同時仍然保持與可能由 Python 2 建立的陣列的相容性。

(gh-18657)

變更#

numpy.piecewise 輸出類別現在與輸入類別相符#

當在 ndarray 子類別用作 piecewise 的輸入時,它們會傳遞給函數。輸出現在也將是相同的子類別。

(gh-18110)

啟用 Accelerate Framework#

隨著 macOS 11.3 的發布,numpy 在使用 Accelerate Framework 的 BLAS 和 LAPACK 實作時遇到的一些不同問題應已解決。此變更在 macOS 上啟用 Accelerate Framework 作為一個選項。如果發現其他問題,請使用開發人員意見回饋助理工具 (https://developer.apple.com/bug-reporting/) 提交關於 Accelerate 的錯誤報告。我們打算立即解決問題,並計劃繼續支援和更新我們的 BLAS 和 LAPACK 函式庫。

(gh-18874)