我在使用NumPy時遇到的一個重複性錯誤是,嘗試索引數組失敗,因爲數組的維度之一是單例,因此該維度已被清除,被索引。這在設計用於對任意大小的數組進行操作的函數中尤其成問題。我正在尋找最便宜,最普遍的方法來避免這種錯誤。處理python數組中的維度崩潰
下面是一個例子:
import numpy as np
f = (lambda t, u, i=0: t[:,i]*u[::-1])
a = np.eye(3)
b = np.array([1,2,3])
f(a,b)
f(a[:,0],b[1])
第一個電話按預期工作。第二次調用失敗的方式有兩種:1)t
不能被[:,0]
索引,因爲它的形狀爲(3,)
,並且2)u
根本不能被索引,因爲它是一個標量。
下面是發生在我身上的修復:
1)使用np.atleast_1d
和np.atleast_2d
等(可能用條件,以確保尺寸是按照正確的順序)內f
,以確保所有參數都他們需要的尺寸。這排除了lambda的使用,並且可以採用我不想要的幾條線。
2)而不是上面寫f(a[:,0],b[1])
,使用f(a[:,[0]],b[[1]])
。這很好,但我總是必須記住放入額外的括號中,如果索引存儲在一個變量中,您可能不知道是否應該放入額外的括號。例如: -
idx = 1
f(a[:,[0]],b[[idx]])
idx = [2,0,1]
f(a[:,[0]],b[idx])
在這種情況下,你似乎不得不呼籲idx
np.atleast_1d
第一,這可能比把np.atleast_1d
在功能上更加繁瑣。
3)在某些情況下,我可以擺脫只是不放入索引。例如:
f = lambda t, u: t[0]*u
f(a,b)
f(a[:,0],b[0])
這是有效的,當它適用時顯然是最光滑的解決方案。但是在任何情況下都沒有幫助(特別是,您的維度必須以正確的順序開始)。
那麼,有沒有比上述更好的方法?
許多numpy函數都有很多python代碼行,它們在執行中央操作之前對輸入進行重塑和按摩。看看'atleast_1d'的功能(10行)。 – hpaulj
我感到你的痛苦。下面是我通常如何處理這個問題:首先,我存儲輸入形狀,並檢查輸入是否是標量,然後我應用'np.atleast_1d'這樣的函數進行計算,最後重新調整結果以匹配輸入形狀(例如變回標量)。下行:這是很多樣板。上行:更靈活的接口,並且對於呼叫者而言更少意外。我認爲這是一個相當普遍的功能,它是你的域特定庫的一部分。 – Lemming