NumPy 1.25.0 發行說明#

NumPy 1.25.0 版本持續進行改進 dtypes 的處理和升級、提高執行速度以及釐清文件的工作。同時也為了未來的 NumPy 2.0.0 版本發布做準備,導致大量新的和過期的棄用。重點如下:

  • 支援 MUSL,現在有 MUSL wheels。

  • 支援 Fujitsu C/C++ 編譯器。

  • einsum 現在支援物件陣列

  • 支援原地矩陣乘法 (@=)。

當 Python 3.12 發布時,我們將會發布 NumPy 1.26。這是必要的,因為 Python 3.12 已捨棄 distutils,而我們將會切換使用 meson 進行未來的建置。下一個主線版本將會是 NumPy 2.0.0。我們計劃 2.0 系列仍將支援針對早期 NumPy 版本建置的下游專案。

此版本支援的 Python 版本為 3.9-3.11。

棄用#

  • np.core.MachAr 已棄用。它是私有 API。在 np.core 中定義的名稱通常應被視為私有的。

    (gh-22638)

  • np.finfo(None) 已棄用。

    (gh-23011)

  • np.round_ 已棄用。請改用 np.round

    (gh-23302)

  • np.product 已棄用。請改用 np.prod

    (gh-23314)

  • np.cumproduct 已棄用。請改用 np.cumprod

    (gh-23314)

  • np.sometrue 已棄用。請改用 np.any

    (gh-23314)

  • np.alltrue 已棄用。請改用 np.all

    (gh-23314)

  • 只有 ndim-0 陣列會被視為純量。NumPy 過去將所有大小為 1 的陣列 (例如,np.array([3.14])) 視為純量。未來,這將僅限於 ndim 為 0 的陣列 (例如,np.array(3.14))。以下運算式將會報告棄用警告

    a = np.array([3.14])
    float(a)  # better: a[0] to get the numpy.float or a.item()
    
    b = np.array([[3.14]])
    c = numpy.random.rand(10)
    c[0] = b  # better: c[0] = b[0, 0]
    

    (gh-10615)

  • np.find_common_type 已棄用。numpy.find_common_type 現在已棄用,其使用應替換為 numpy.result_typenumpy.promote_types。大多數使用者將 scalar_types 的第二個參數保留為 [],在這種情況下,np.result_typenp.promote_types 都更快且更穩健。當不使用 scalar_types 時,主要差異在於替換項有意將非原生位元組順序轉換為原生位元組順序。此外,find_common_type 會傳回 object dtype,而不是促銷失敗。當輸入不全是數值時,這會導致差異。重要的是,這也會發生在例如 timedelta/datetime 的情況,NumPy 的促銷規則目前有時會令人感到意外。

    scalar_types 參數不是 [] 時,情況會更複雜。在大多數情況下,使用 np.result_type 並傳遞 Python 值 00.00j 的結果,與在 scalar_types 中使用 intfloatcomplex 相同。

    當建構 scalar_types 時,np.result_type 是正確的替換項,並且可以傳遞純量值,例如 np.float32(0.0)。傳遞 0 以外的值可能會導致值檢查行為 (這是 np.find_common_type 從未使用過的,而 NEP 50 未來可能會變更)。在這種情況下,行為的主要可能變更是在陣列類型為帶正負號整數,而純量類型為不帶正負號時。

    如果您不確定如何替換 scalar_types 的使用,或何時可能出現非數值 dtype,請隨時開啟 NumPy issue 尋求協助。

    (gh-22539)

過期的棄用#

  • np.core.macharnp.finfo.machar 已移除。

    (gh-22638)

  • 當 dtype 不是數值 (且未定義正數) 時,+arr 現在會引發錯誤。

    (gh-22998)

  • 現在必須將序列傳遞到堆疊系列函式 (stackvstackhstackdstackcolumn_stack)。

    (gh-23019)

  • np.clip 現在預設為 same-kind casting。回退到 unsafe casting 已在 NumPy 1.17 中棄用。

    (gh-23403)

  • np.clip 現在會傳播作為 minmax 傳遞的 np.nan 值。先前,純量 NaN 通常會被忽略。這已在 NumPy 1.17 中棄用。

    (gh-23403)

  • np.dual 子模組已移除。

    (gh-23480)

  • NumPy 現在總是忽略類陣列 (定義其中一個陣列協定) 的序列行為。(棄用始於 NumPy 1.20)

    (gh-23660)

  • astype 或陣列建立函式 (例如 asarray) 中轉換為子陣列 dtype 時,小眾的 FutureWarning 現在已最終確定。現在的行為總是與子陣列 dtype 包裝到單個欄位時相同 (這是先前的解決方法)。(自 NumPy 1.20 以來的 FutureWarning)

    (gh-23666)

  • ==!= 警告已最終確定。陣列上的 ==!= 運算子現在總是

    • 引發比較期間發生的錯誤,例如當陣列具有不相容的形狀時 (np.array([1, 2]) == np.array([1, 2, 3]))。

    • 當值在根本上不可比較時 (例如,具有不同的 dtype),傳回全部 True 或全部 False 的陣列。一個範例是 np.array(["a"]) == np.array([1])

      這模仿了 Python 在比較不相容類型 (例如 "a" == 1"a" != 1) 時傳回 FalseTrue 的行為。長期以來,這些都給出了 DeprecationWarningFutureWarning

    (gh-22707)

  • Nose 支援已移除。NumPy 在 2018 年切換為使用 pytest,而 nose 多年來一直未維護。我們保留了 NumPy 的 nose 支援,以避免破壞可能一直在使用它且尚未切換到 pytest 或其他測試框架的下游專案。隨著 Python 3.12 的到來,未修補的 nose 將會引發錯誤。現在是時候繼續前進了。

    已移除的裝飾器:

    • raises

    • slow

    • setastest

    • skipif

    • knownfailif

    • deprecated

    • parametrize

    • _needs_refcount

    這些不應與具有相似名稱的 pytest 版本混淆,例如,pytest.mark.slow、pytest.mark.skipif、pytest.mark.parametrize。

    已移除的函式:

    • Tester

    • import_nose

    • run_module_suite

    (gh-23041)

  • numpy.testing.utils shim 已移除。從 numpy.testing.utils shim 匯入自 2019 年以來已棄用,shim 現在已移除。所有匯入都應直接從 numpy.testing 進行。

    (gh-23060)

  • 用於停用調度的環境變數已移除。已移除對 NUMPY_EXPERIMENTAL_ARRAY_FUNCTION 環境變數的支援。此變數停用了使用 __array_function__ 的調度。

    (gh-23376)

  • 已移除對 y= 作為 out= 別名的支援。fixisposinfisneginf 函式允許使用 y= 作為 out= 的 (已棄用) 別名。現在不再支援此功能。

    (gh-23376)

相容性注意事項#

  • busday_count 方法現在可以正確處理 begindates 的時間晚於 enddates 的情況。先前,即使文件說明始終排除 enddates,它仍會被包含在內。

    (gh-23229)

  • 當使用 np.equalnp.not_equal 比較 datetime 和 timedelta 時,numpy 先前允許使用 casting="unsafe" 進行比較。此操作現在會失敗。使用 dtype kwarg 強制輸出 dtype 可以使操作成功,但我們不建議這樣做。

    (gh-22707)

  • 當使用 np.load 從檔案控制代碼載入資料時,如果控制代碼位於檔案末尾 (當透過重複呼叫 np.load 讀取多個陣列時可能會發生這種情況),如果 allow_pickle=False,numpy 先前會引發 ValueError,如果 allow_pickle=True,則會引發 OSError。現在,在兩種情況下,它都會引發 EOFError

    (gh-23105)

np.padmode=wrap 使用原始資料的嚴格倍數進行填充#

當填充大小大於初始陣列時,基於早期版本 pad (使用 mode="wrap") 的程式碼將會傳回不同的結果。

即使填充大小大於初始陣列,np.padmode=wrap 現在也總是使用原始資料的嚴格倍數填充空間。

(gh-22575)

Cython long_tulong_t 已移除#

long_tulong_tlonglong_tulonglong_t 的別名,並且令人困惑 (Python 2 的遺留物)。此變更可能會導致錯誤

'long_t' is not a type identifier
'ulong_t' is not a type identifier

我們建議使用位元大小的類型,例如 cnp.int64_t,或使用 cnp.intp_t,它在 32 位元系統上為 32 位元,在 64 位元系統上為 64 位元 (這與索引最相容)。如果需要 C long,請使用純 longnpy_longcnp.int_t 也是 long (NumPy 的預設整數)。但是,在 64 位元 Windows 上,long 為 32 位元,我們可能希望即使在 NumPy 中也調整此設定。(如果您對此感到好奇,請隨時聯絡 NumPy 開發人員。)

(gh-22637)

變更 ufunc 的錯誤 axes 引數的錯誤訊息和類型#

當錯誤的 axes 值傳遞給 ufunc(..., axes=[...])` 時,錯誤訊息和類型已變更。訊息現在更能指示問題,如果值不符,將會引發 AxisError。對於無效的輸入類型,仍會引發 TypeError

(gh-22675)

如果類陣列定義了 __array_ufunc__,現在可以在用作 where 時覆寫 ufunc#

如果 numpy.ufuncwhere 關鍵字引數是 numpy.ndarray 的子類別,或是定義了 numpy.class.__array_ufunc__ 的 duck type,則可以使用與輸入和輸出引數相同的機制來覆寫 ufunc 的行為。請注意,為了使此功能正常運作,where.__array_ufunc__ 實作將必須解包 where 引數,以將其傳遞到 ufunc 的預設實作中,或者對於 numpy.ndarray 子類別,在使用 super().__array_ufunc__ 之前。

(gh-23240)

預設情況下,針對 NumPy C API 進行編譯現在向後相容#

NumPy 現在預設為公開 C-API 的向後相容子集。這使得使用 oldest-supported-numpy 變得不必要。程式庫可以覆寫預設的最小版本,以與使用相容

#define NPY_TARGET_VERSION NPY_1_22_API_VERSION

在包含 NumPy 之前,或透過將等效的 -D 選項傳遞給編譯器。NumPy 1.25 預設值為 NPY_1_19_API_VERSION。由於 NumPy 1.19 C API 與 NumPy 1.16 C API 相同,因此產生的程式將與 NumPy 1.16 相容 (從 C-API 的角度來看)。此預設值將在未來的非錯誤修正版本中增加。您仍然可以針對較舊的 NumPy 版本進行編譯,並在較新的版本上執行。

如需更多詳細資訊,請參閱 給下游套件作者

(gh-23528)

新功能#

np.einsum 現在接受具有 object dtype 的陣列#

程式碼路徑將會呼叫物件 dtype 陣列上的 python 運算子,就像 np.dotnp.matmul 一樣。

(gh-18053)

新增對原地矩陣乘法的支援#

現在可以透過 @= 運算子執行原地矩陣乘法。

>>> import numpy as np

>>> a = np.arange(6).reshape(3, 2)
>>> print(a)
[[0 1]
 [2 3]
 [4 5]]

>>> b = np.ones((2, 2), dtype=int)
>>> a @= b
>>> print(a)
[[1 1]
 [5 5]
 [9 9]]

(gh-21120)

新增 NPY_ENABLE_CPU_FEATURES 環境變數#

使用者現在可以透過指定 NPY_ENABLE_CPU_FEATURES 環境變數,選擇僅在執行階段啟用已建置 CPU 功能的子集。請注意,這些指定的功能必須在基準線之外,因為這些功能始終被假定存在。如果嘗試啟用的功能不受您的 CPU 支援,或 NumPy 未使用該功能建置,則會引發錯誤。

(gh-22137)

NumPy 現在有一個 np.exceptions 命名空間#

NumPy 現在有一個專用的命名空間,使大多數例外和警告可用。所有這些都保留在主要命名空間中,儘管將來某些可能會慢慢移動。這樣做的主要原因是為了提高可探索性並新增未來的例外。

(gh-22644)

np.linalg 函式傳回 NamedTuples#

傳回元組的 np.linalg 函式現在傳回 namedtuples。這些函式是 eig()eigh()qr()slogdet()svd()。在這些函式使用某些關鍵字引數傳回非元組 (例如 svd(compute_uv=False)) 的情況下,傳回類型保持不變。

(gh-22786)

np.char 中的字串函式與 NEP 42 自訂 dtypes 相容#

代表 unicode 字串或位元組字串的自訂 dtypes 現在可以傳遞到 np.char 中的字串函式。

(gh-22863)

字串 dtype 實例可以從字串抽象 dtype 類別建立#

現在可以建立具有大小的字串 dtype 實例,而無需使用 dtype 的字串名稱。例如,type(np.dtype('U'))(8) 將建立一個等效於 np.dtype('U8') 的 dtype。當編寫處理字串 dtype 類別的通用程式碼時,此功能最有用。

(gh-22963)

現在支援 Fujitsu C/C++ 編譯器#

已新增對 Fujitsu 編譯器的支援。若要使用 Fujitsu 編譯器建置,請執行

python setup.py build -c fujitsu

現在支援 SSL2#

已新增對 SSL2 的支援。SSL2 是一個提供與 OpenBLAS 相容的 GEMM 函式的程式庫。若要啟用 SSL2,需要編輯 site.cfg 並使用 Fujitsu 編譯器建置。請參閱 site.cfg.example。

(gh-22982)

改進#

NDArrayOperatorsMixin 指定它沒有 __slots__#

NDArrayOperatorsMixin 類別現在指定它不包含 __slots__,確保子類別現在可以在 Python 中使用此功能。

(gh-23113)

修正複數零的次方#

np.power 現在針對複數的 0^{non-zero} 傳回不同的結果。請注意,僅當指數的實部大於零時,該值才被定義。先前,除非虛部嚴格為零,否則會傳回 NaN。傳回值為 0+0j0-0j

(gh-18535)

新的 DTypePromotionError#

NumPy 現在有一個新的 DTypePromotionError,當兩個 dtypes 無法升級為通用 dtype 時使用,例如

np.result_type("M8[s]", np.complex128)

引發這個新的例外。

(gh-22707)

np.show_config 使用來自 Meson 的資訊#

建置和系統資訊現在包含來自 Meson 的資訊。np.show_config 現在有一個新的可選參數 mode,以協助自訂輸出。

(gh-22769)

修正使用引數 prepend/append 呼叫時,np.ma.diff 未保留遮罩的問題。#

現在使用引數 prepend 和/或 append 呼叫 np.ma.diff 會傳回保留輸入遮罩的 MaskedArray

先前,會傳回沒有遮罩的 MaskedArray

(gh-22776)

修正 Cython 中 NumPy C-API 的錯誤處理#

許多為在 Cython 中使用而定義的 NumPy C 函式都缺少正確的錯誤指示器,例如 except -1except *。現在已新增這些指示器。

(gh-22997)

直接產生隨機數字產生器的能力#

numpy.random.Generator.spawn 現在允許透過 numpy.random.SeedSequence.spawn 機制直接產生新的獨立子產生器。numpy.random.BitGenerator.spawn 對於底層位元產生器執行相同的操作。

此外,numpy.random.BitGenerator.seed_seq 現在可以直接存取用於初始化位元產生器的種子序列。例如,這允許

seed = 0x2e09b90939db40c400f8f22dae617151
rng = np.random.default_rng(seed)
child_rng1, child_rng2 = rng.spawn(2)

# safely use rng, child_rng1, and child_rng2

先前,如果不顯式傳遞 SeedSequence,則很難做到這一點。請參閱 numpy.random.SeedSequence 以取得更多資訊。

(gh-23195)

numpy.logspace 現在支援非純量 base 引數#

如果 numpy.logspacebase 引數可與 startstop 引數廣播,則現在可以為類陣列。

(gh-23275)

np.ma.dot() 現在支援非 2d 陣列#

先前,只有當 ab 都是 2d 時,np.ma.dot() 才有效。現在,它也適用於非 2d 陣列,就像 np.dot() 一樣。

(gh-23322)

在 repr 中明確顯示 .npz 檔案的索引鍵#

列印時,NpzFile 會顯示已載入 .npz 檔案的索引鍵。

>>> npzfile = np.load('arr.npz')
>>> npzfile
NpzFile 'arr.npz' with keys arr_0, arr_1, arr_2, arr_3, arr_4...

(gh-23357)

NumPy 現在在 np.dtypes 中公開 DType 類別#

新的 numpy.dtypes 模組現在公開 DType 類別,並將包含未來與 dtype 相關的功能。大多數使用者應該不需要直接使用這些類別。

(gh-23358)

在 .npy 或 .npz 檔案中儲存之前,捨棄 dtype metadata#

目前,包含具有 metadata 的 dtype 表格的 *.npy 檔案無法讀回。現在,np.savenp.savez 會在儲存之前捨棄 metadata。

(gh-23371)

numpy.lib.recfunctions.structured_to_unstructured 在更多情況下傳回檢視#

如果欄位之間的步幅是常數,structured_to_unstructured 現在會傳回檢視。先前,欄位之間的填充或反轉欄位會導致複製。此變更僅適用於 ndarraymemmaprecarray。對於所有其他陣列子類別,行為保持不變。

(gh-23652)

帶正負號和不帶正負號的整數始終正確比較#

uint64int64 在 NumPy 中混合使用時,NumPy 通常會將兩者都提升為 float64。這種行為可能存在爭議,但對於比較運算子 ==<= 來說,可能會造成混淆,因為返回的結果可能不正確,但轉換過程卻被隱藏了,因為結果是一個布林值。NumPy 現在將返回這些運算子的正確結果,方法是避免轉換為浮點數。

(gh-23713)

效能改進和變更#

在啟用 AVX-512 的處理器上,np.argsort 速度更快#

針對支援 AVX-512 指令集的處理器,np.argsort 的 32 位元和 64 位元快速排序演算法速度提升高達 6 倍。

感謝 Intel 公司 贊助這項工作。

(gh-23707)

在啟用 AVX-512 的處理器上,np.sort 速度更快#

針對支援 AVX-512 指令集的處理器,16 位元和 64 位元資料類型的快速排序速度提升高達 15 倍和 9 倍。

感謝 Intel 公司 贊助這項工作。

(gh-22315)

__array_function__ 機制現在快得多#

NumPy 中大多數函數的 overhead 現在更小了,尤其是在使用關鍵字參數時。此變更顯著加快了許多簡單的函數呼叫。

(gh-23020)

ufunc.at 可能會快得多#

通用 ufunc.at 最多可快 9 倍。實現此加速的條件:

  • 運算元已對齊

  • 沒有類型轉換

如果 ufuncs 在滿足上述條件的情況下,對 1 維參數使用適當的索引迴圈,則 ufunc.at 最多可快 60 倍(額外加速 7 倍)。已將適當的索引迴圈添加到 addsubtractmultiplyfloor_dividemaximumminimumfmaxfmin

內部邏輯與用於常規 ufuncs 的邏輯類似,後者也具有快速路徑。

感謝 D. E. Shaw group 贊助這項工作。

(gh-23136)

NpzFile 上的成員資格測試速度更快#

如果成員資格測試成功,NpzFile 上的成員資格測試將不再解壓縮封存檔。

(gh-23661)

變更#

具有特定純量值的 np.r_[]np.c_[]#

在極少數情況下,主要使用 np.r_ 與純量可能會導致不同的結果。以下範例突顯了主要的潛在變更:

>>> np.r_[np.arange(5, dtype=np.uint8), -1].dtype
int16  # rather than the default integer (int64 or int32)
>>> np.r_[np.arange(5, dtype=np.int8), 255]
array([  0,   1,   2,   3,   4, 255], dtype=int16)

第二個範例返回:

array([ 0,  1,  2,  3,  4, -1], dtype=int8)

第一個範例是由帶符號整數純量與無符號整數陣列所造成,而第二個範例是由於 255 不符合 int8,而 NumPy 目前會檢查值以使其正常運作。(請注意,由於 NEP 50,第二個範例預計在未來會變更;屆時將引發錯誤。)

(gh-22539)

大多數 NumPy 函數都封裝在 C 可調用物件中#

為了加速 __array_function__ 調度,大多數 NumPy 函數現在都封裝在 C 可調用物件中,而不是真正的 Python 函數或 C 方法。它們的外觀和感覺仍然與以前相同(就像 Python 函數一樣),這應該只會提高效能和使用者體驗(更清晰的回溯)。但是,如果此變更在某些方面使您的程式感到困惑,請告知 NumPy 開發人員。

(gh-23020)

C++ 標準函式庫使用#

NumPy 建置現在依賴 C++ 標準函式庫,因為 numpy.core._multiarray_umath 擴充功能與 C++ 連結器連結。

(gh-23601)