NEP 34 — 禁止從序列推斷 dtype=object
#
- 作者:
Matti Picus
- 狀態:
最終
- 類型:
標準追蹤
- 建立於:
2019-10-10
- 決議:
https://mail.python.org/pipermail/numpy-discussion/2019-October/080200.html
摘要#
當使用者使用序列的序列建立陣列時,他們有時會在匹配巢狀序列的長度時出錯,通常稱為「參差不齊的陣列」。在這裡,我們將它們稱為參差不齊的巢狀序列。透過 np.array([<ragged_nested_sequence>])
建立此類陣列,且沒有 dtype
關鍵字引數,今天將預設為 object
-dtype 陣列。變更行為以引發 ValueError
例外。
動機和範疇#
使用者在透過 np.array
建立 numpy.ndarray 時指定列表的列表,可能會錯誤地傳入不同長度的列表。目前我們接受此輸入並自動建立 dtype=object
的陣列。這可能會造成混淆,因為這很少是使用者期望的結果。變更自動 dtype 偵測,使其永遠不會針對參差不齊的巢狀序列 (定義為序列的遞迴序列,其中同一層級上的序列並非全部具有相同的長度) 傳回 object
,將強制實際希望建立 object
陣列的使用者明確指定該 dtype。請注意,lists
、tuples
和 nd.ndarrays
都是序列 [0]。例如,請參閱 issue 5303。
用法和影響#
在此變更之後,使用參差不齊的巢狀序列建立陣列必須明確定義 dtype
>>> np.array([[1, 2], [1]])
ValueError: cannot guess the desired dtype from the input
>>> np.array([[1, 2], [1]], dtype=object)
# succeeds, with no change from current behaviour
棄用將會影響任何內部呼叫 np.asarray
的呼叫。例如,assert_equal
函數系列會呼叫 np.asarray
,因此使用者必須變更如下程式碼:
np.assert_equal(a, [[1, 2], 3])
改為:
np.assert_equal(a, np.array([[1, 2], 3], dtype=object))
詳細描述#
若要明確設定物件陣列的形狀,因為有時很難確定所需的形狀,可以使用:
>>> arr = np.empty(correct_shape, dtype=object)
>>> arr[...] = values
我們也將拒絕非序列和序列的混合序列,例如,以下所有序列都將被拒絕:
>>> arr = np.array([np.arange(10), [10]])
>>> arr = np.array([[range(3), range(3), range(3)], [range(3), 0, 0]])
實作方式#
要變更的程式碼位於 PyArray_GetArrayParamsFromObject
和內部 discover_dimensions
函數中。PR 14794 中的第一個實作導致許多下游函式庫故障,並在 1.18 版本發布之前還原。隨後,下游函式庫修正了它們使用參差不齊陣列的地方。重新實作成為 PR 15119,已合併至 1.19 版本。
向後相容性#
任何依賴從參差不齊的巢狀序列建立物件陣列的人員,都需要修改其程式碼。將會有一個棄用期,在此期間,目前的行為將發出 DeprecationWarning
。
替代方案#
我們可以繼續維持現狀。
也有人建議在陣列建立中新增 kwarg
depth
,或者或許新增另一個陣列建立 API 函數ragged_array_object
。目標是消除從array([[1, 2], [1]], dtype=object)
建立物件陣列時的歧義:傳回的陣列應該具有(1,)
或(2,)
的形狀嗎?此 NEP 並未處理該問題,僅棄用在沒有dtype=object
的情況下,將array
用於參差不齊的巢狀序列。參差不齊巢狀序列的使用者未來可能會面臨另一個棄用週期。理由:我們預期很少有使用者打算那樣使用參差不齊的陣列,這從來都不是 NumPy 陣列的預期用途。使用者最好使用另一個函式庫,或只是使用列表的列表。也有人建議棄用所有自動建立
object
-dtype 陣列,這將需要為類似np.array([Decimal(10), Decimal(10)])
的事物新增明確的dtype=object
。這也超出目前 NEP 的範圍。理由:更難評估此較大變更的影響,我們不確定這可能會影響多少使用者。
討論#
issue 5303 的評論指出,早在 2014 年,這就是非預期的行為。隨後幾年提出了變更它的建議,但沒有任何建議被採納。PR 14794 中的 WIP 實作似乎指向此方法的可行性。
參考資料和註腳#
著作權#
本文档已置于公共领域。