NumPy 2.1.0 發行說明#

NumPy 2.1.0 提供對即將到來的 Python 3.13 版本的支援,並停止支援 Python 3.9。除了常見的錯誤修正和更新的 Python 支援外,它幫助我們在 2.0 的擴展開發之後回到我們通常的發行週期。此版本的重點是

  • 支援 array-api 2023.12 標準。

  • 支援 Python 3.13。

  • 初步支援自由執行緒 Python 3.13。

此版本支援 Python 3.10-3.13 版本。

新函數#

新函數 numpy.unstack#

新增了一個函數 np.unstack(array, axis=...),它沿著軸將陣列分割成陣列的元組。它作為 numpy.stack 的反向操作。

(gh-26579)

棄用#

  • numpy.savefix_imports 關鍵字引數已被棄用。自 NumPy 1.17 以來,numpy.save 使用不再支援 Python 2 的 pickle 協定,並忽略 fix_imports 關鍵字。此關鍵字僅為向後相容性而保留。現在已被棄用。

    (gh-26452)

  • 將非整數輸入作為 bincount 的第一個引數傳遞現在已被棄用,因為此類輸入會靜默地轉換為整數,且沒有關於精度損失的警告。

    (gh-27076)

已過期的棄用#

  • 純量和 0D 陣列不允許用於 numpy.nonzeronumpy.ndarray.nonzero

    (gh-26268)

  • set_string_function 內部函數已被移除,且 PyArray_SetStringFunction 已被移除。

    (gh-26611)

C API 變更#

API 符號現在預設隱藏但可自訂#

NumPy 現在預設隱藏它新增的 API 符號,以允許所有 NumPy API 使用。這表示預設情況下,您無法從另一個程式庫動態擷取 NumPy API(這在 Windows 上從未可行)。

如果您遇到與 PyArray_APIPyArray_RUNTIME_VERSION 相關的連結錯誤,您可以定義 NPY_API_SYMBOL_ATTRIBUTE 以選擇退出此變更。

如果您由於上游標頭包含 NumPy 而遇到問題,解決方案是確保在它們的標頭之前 #include "numpy/ndarrayobject.h",並根據 including-the-c-api 自行匯入 NumPy。

(gh-26103)

從 npy_3kcompat.h 中移除許多墊片#

npy_3kcompat.h 中移除許多舊的墊片和輔助函數。如果您發現自己需要這些,請將該檔案的先前版本供應到您的程式碼庫中。

(gh-26842)

新的 PyUFuncObject 欄位 process_core_dims_func#

欄位 process_core_dims_func 已新增至結構 PyUFuncObject。對於廣義 ufuncs,此欄位可以設定為 PyUFunc_ProcessCoreDimsFunc 類型的函數,該函數將在呼叫 ufunc 時呼叫。它允許 ufunc 作者檢查核心維度是否滿足其他約束,並在尚未提供輸出核心維度大小時設定它們。

(gh-26908)

新功能#

初步支援自由執行緒 CPython 3.13#

CPython 3.13 將作為實驗性自由執行緒版本提供。請參閱 https://py-free-threading.github.ioPEP 703CPython 3.13 發行說明,以取得關於自由執行緒 Python 的更多詳細資訊。

NumPy 2.1 初步支援 CPython 3.13 的自由執行緒版本。此支援是透過修正 NumPy 中的許多 C 執行緒安全問題而啟用的。在 NumPy 2.1 之前,NumPy 使用大量 C 全域靜態變數來儲存執行階段快取和其他狀態。我們已重構以避免對全域狀態的需求,將全域狀態轉換為執行緒本機狀態,或新增鎖定。

支援自由執行緒 Python 並不表示 NumPy 是執行緒安全的。對 ndarray 的唯讀共享存取應該是安全的。NumPy 公開了共享可變狀態,我們沒有在陣列物件本身中新增任何鎖定,以序列化對共享狀態的存取。如果想要在多個執行緒中變更同一個陣列,則必須在使用者程式碼中謹慎避免競爭情況。透過在多個執行緒中同時變更陣列,例如同時呼叫 ufunc 和 resize 方法,肯定有可能使 NumPy 崩潰。目前我們的指導原則是:「不要那樣做」。未來我們希望提供更強的保證。

物件陣列尤其需要特別注意,因為 GIL 先前為物件陣列存取提供了鎖定,但現在不再提供。有關自由執行緒版本中物件陣列的更多資訊,請參閱 Issue #27199

如果您對自由執行緒 Python 感興趣,例如因為您有基於多處理的工作流程,並且有興趣使用 Python 執行緒執行,我們鼓勵您進行測試和實驗。

如果您遇到您懷疑是由於 NumPy 引起的問題,請開啟問題,首先檢查該錯誤是否也發生在「常規」非自由執行緒 CPython 3.13 版本中。許多執行緒錯誤也可能發生在釋放 GIL 的程式碼中;停用 GIL 只會更容易觸發執行緒錯誤。

(gh-26157)

  • numpy.reshapenumpy.ndarray.reshape 現在支援 shapecopy 引數。

    (gh-26292)

  • NumPy 現在支援 DLPack v1,未來將棄用對舊版本的支援。

    (gh-26501)

  • numpy.asanyarray 現在支援 copydevice 引數,與 numpy.asarray 相符。

    (gh-26580)

  • numpy.printoptionsnumpy.get_printoptionsnumpy.set_printoptions 現在支援一個新選項 override_repr,用於定義自訂 repr(array) 行為。

    (gh-26611)

  • numpy.cumulative_sumnumpy.cumulative_prod 已新增為與 Array API 相容的替代方案,以取代 numpy.cumsumnumpy.cumprod。新函數可以在結果中包含固定的初始值(sum 為零,prod 為一)。

    (gh-26724)

  • numpy.clip 現在支援 maxmin 關鍵字引數,這些引數旨在取代 a_mina_max。此外,對於 np.clip(a)np.clip(a, None, None),將傳回輸入陣列的副本,而不是引發錯誤。

    (gh-26724)

  • numpy.astype 現在支援 device 引數。

    (gh-26724)

f2py 可以產生與自由執行緒相容的 C 擴充功能#

--freethreading-compatible 傳遞給 f2py CLI 工具,以產生標記為與自由執行緒 CPython 直譯器相容的 C 擴充功能。這樣做可以防止直譯器在匯入 C 擴充功能時重新啟用執行階段的 GIL。請注意,f2py 不會分析 Fortran 程式碼的執行緒安全性,因此您必須先驗證封裝的 Fortran 程式碼是否為執行緒安全,然後再將擴充功能標記為相容。

(gh-26981)

改善#

histogram 自動分箱現在針對整數輸入資料傳回 >=1 的箱大小#

對於整數輸入資料,小於 1 的箱大小會導致虛假的空箱。當使用 histogram_bin_edges 提供的演算法之一計算箱數量時,現在可以避免這種情況。

(gh-12150)

ndarray 形狀類型參數現在是共變的,並繫結到 tuple[int, ...]#

ndarray 的靜態類型標註是一項長期工作,此變更將繼續進行。它是一種泛型類型,具有用於形狀和資料類型的類型參數。先前,形狀類型參數可以是任何值。此變更將其限制為整數元組,正如人們從使用 ndarray.shape 所預期的那樣。此外,形狀類型參數已從不變變更為共變。此變更也適用於 ndarray 的子類型,例如 numpy.ma.MaskedArray。有關更多資訊,請參閱 typing 文件

(gh-26081)

使用方法 closest_observationnp.quantile 選擇最近的偶數階統計量#

這將邊界情況下最近的定義從最近的奇數階統計量變更為最近的偶數階統計量。NumPy 實作現在與其他參考實作相符。

(gh-26656)

lapack_lite 現在是執行緒安全的#

NumPy 提供了一個名為 lapack_lite 的 LAPACK 的最小低效能版本,如果建置時未偵測到 BLAS/LAPACK 系統,則可以使用它。

到目前為止,lapack_lite 不是執行緒安全的。單執行緒的使用案例沒有遇到任何問題,但在多個執行緒中執行線性代數運算可能會由於資料競爭而導致錯誤、不正確的結果或區段錯誤。

我們新增了一個全域鎖定,以序列化在多個執行緒中對 lapack_lite 的存取。

(gh-26750)

numpy.printoptions 內容管理器現在是執行緒和非同步安全的#

在 NumPy 的先前版本中,printoptions 是使用 Python 和 C 全域變數的組合定義的。我們已重構,因此狀態儲存在 Python ContextVar 中,使內容管理器成為執行緒和非同步安全的。

(gh-26846)

類型提示 numpy.polynomial#

從 2.1 版本開始,已包含 numpy.polynomial 及其子套件中函數和便利類別的 PEP 484 類型註釋。

(gh-26897)

改善的 numpy.dtypes 類型提示#

numpy.dtypes 的類型註釋現在更好地反映了執行階段:numpy.dtype 類型別名已替換為專門的 dtype *子類型*,並且先前遺失的 numpy.dtypes.StringDType 註釋已新增。

(gh-27008)

效能改善和變更#

  • numpy.save 現在使用 pickle 協定版本 4 來儲存具有物件 dtype 的陣列,這允許 pickle 物件大於 4GB,並將大型陣列的儲存速度提高約 5%。

    (gh-26388)

  • 在 x86_64 和 i686 上的 OpenBLAS 是使用較少的核心建置的。根據基準測試,這些核心周圍有 5 個效能叢集:PRESCOTT NEHALEM SANDYBRIDGE HASWELL SKYLAKEX

    (gh-27147)

  • Windows 上的 OpenBLAS 在連結時不包含 quadmath,簡化了授權。

    (gh-27147)

  • 由於 Windows 上 OpenBLAS 的回歸,因此還原了針對 OpenBLAS 0.3.26 使用多個執行緒時的效能改善。

    (gh-27147)

ma.covma.corrcoef 現在顯著更快#

私有函數已與 ma.covma.corrcoef 一起重構。它們現在顯著更快,尤其是在大型遮罩陣列上。

(gh-26285)

變更#

  • 由於 numpy.vecdot 現在是 ufunc,因此它的簽章精度較低。這是由於 ufunc 的類型標記的限制。

    (gh-26313)

  • numpy.floornumpy.ceilnumpy.trunc 現在不會對整數和布林 dtype 輸入陣列執行轉換為浮點 dtype 的操作。

    (gh-26766)

ma.corrcoef 可能會傳回略有不同的結果#

成對觀察方法目前用於 ma.corrcoef 中,以計算每對變數的標準差。這已變更,因為它用於標準化共變異數,使用 ma.cov 估計,後者不以成對方式考慮每個變數的觀察值,使其變得不必要。標準化已替換為每個變數更適當的標準差,這顯著減少了執行時間,但在變數對之間的觀察值未對齊的情況下,將傳回略有不同的相關係數估計值。但是,在所有其他情況下,它將傳回相同的估計值,包括在使用沒有遮罩值的遮罩陣列時,傳回與 corrcoef 相同的相關矩陣。

(gh-26285)

copytofull 中的轉換安全性修正#

copyto 現在正確地使用 NEP 50,並將其應用於其轉換安全性。Python 整數到 NumPy 整數的轉換和 Python 浮點數到 NumPy 浮點數的轉換現在被視為「安全」,即使賦值可能會失敗或精度可能會遺失。這表示以下範例略有變更

  • np.copyto(int8_arr, 1000) previously performed an unsafe/same-kind cast

    of the Python integer. It will now always raise, to achieve an unsafe cast you must pass an array or NumPy scalar.

  • np.copyto(uint8_arr, 1000, casting="safe") will raise an OverflowError rather than a TypeError due to same-kind casting.

  • np.copyto(float32_arr, 1e300, casting="safe") will overflow to inf (float32 cannot hold 1e300) rather raising a TypeError.

Further, only the dtype is used when assigning NumPy scalars (or 0-d arrays), meaning that the following behaves differently

  • np.copyto(float32_arr, np.float64(3.0), casting="safe") raises.

  • np.coptyo(int8_arr, np.int64(100), casting="safe") raises. Previously, NumPy checked whether the 100 fits the int8_arr.

這使 copytofullfull_like 與正確的 NumPy 2 行為對齊。

(gh-27091)