[英]Python-numpy test for ndarray using ndim
我正在研究一個需要大量數值數組計算的Python項目。 不幸的是(或者幸運的是,取決於你的POV),我是Python的新手,但多年來一直在做MATLAB和Octave編程(APL之前)。 我習慣於將每個變量自動輸入到矩陣浮點數,並且仍然習慣於檢查輸入類型。
在我的許多函數中,我要求輸入S是numpy.ndarray
的大小(n,p)
,所以我必須測試該類型(S)是numpy.ndarray
並獲取值(n,p) = numpy.shape(S)
。 一個潛在的問題是輸入可能是list / tuple / int / etc ......,另一個問題是輸入可能是shape ()
數組: S.ndim = 0
。 在我看來,我可以同時測試變量類型,修復S.ndim = 0
問題,然后得到我的維度:
# first simultaneously test for ndarray and get proper dimensions
try:
if (S.ndim == 0):
S = S.copy(); S.shape = (1,1);
# define dimensions p, and p2
(p,p2) = numpy.shape(S);
except AttributeError: # got here because input is not something array-like
raise AttributeError("blah blah blah");
雖然它有效,但我想知道這是否有效? ndim的文檔字符串說
如果它還不是ndarray,則嘗試轉換。
我們肯定知道numpy可以輕松地將int / tuple / list轉換為數組,所以我很困惑為什么會為這些類型的輸入引發AttributeError,當numpy應該這樣做
numpy.array(S).ndim;
這應該工作。
在為NumPy代碼進行輸入驗證時,我總是使用np.asarray
:
>>> np.asarray(np.array([1,2,3]))
array([1, 2, 3])
>>> np.asarray([1,2,3])
array([1, 2, 3])
>>> np.asarray((1,2,3))
array([1, 2, 3])
>>> np.asarray(1)
array(1)
>>> np.asarray(1).shape
()
此功能具有很好的功能,它只在必要時復制數據; 如果輸入已經是ndarray
,則數據保留在原位(只有類型可能會被更改,因為它也擺脫了那個討厭的np.matrix
)。
ndim的文檔字符串說
這是函數np.ndim
的文檔字符串,而不是ndim
屬性,非NumPy對象沒有。 您可以使用該功能,但效果可能是數據可能被復制兩次,因此請執行以下操作:
S = np.asarray(S)
(p, p2) = S.shape
如果S.ndim != 2
這將引發ValueError
。
[最后說明:你不需要;
在Python中,如果你只是遵循縮進規則。 實際上,Python程序員避開了分號。
鑒於對@larsmans回答的評論,您可以嘗試:
if not isinstance(S, np.ndarray):
raise TypeError("Input not a ndarray")
if S.ndim == 0:
S = np.reshape(S, (1,1))
(p, p2) = S.shape
首先,明確檢查S
是否是ndarray
的(子類)。 然后,如果需要,可以使用np.reshape
復制數據(當然np.reshape
重新整形)。 最后,你得到了維度。
請注意,在大多數情況下, np
函數將首先嘗試訪問ndarray
的相應方法,然后嘗試將輸入轉換為ndarray
(有時將其保留為子類,如np.asanyarray
,有時不會(如np.asarray(...)
)。 np.asarray(...)
,使用方法而不是函數總是更有效:這就是我們使用S.shape
而不是np.shape(S)
。
另一點: np.asarray
, np.asanyarray
, np.atleast_1D
......都是更通用的函數np.array
。 例如, asarray
將array
的可選copy
參數設置為False
, asanyarray
設置相同並設置subok=True
, atleast_1D
設置ndmin=1
, atleast_2d
設置ndmin=2
... np.array
,使用np.array
總是更容易用適當的論據。 但正如一些評論中提到的那樣,這是一種風格問題。 快捷方式通常可以提高可讀性,這始終是一個需要牢記的目標。
在任何情況下,當你使用np.array(..., copy=True)
,你明確地要求提供初始數據的副本,有點像做一個list([....])
。 即使沒有其他更改,您的數據也將被復制。 這有它的缺點的優勢(如我們在法國的說),例如,你可以改變的order
從行第一C
到列第一F
。 但無論如何,你得到你想要的副本。
使用np.array(input, copy=False)
,始終會創建一個新數組。 如果后者已經是ndarray
(也就是說,不浪費內存),它將指向同一塊內存作為input
,或者如果input
不是,則將“從頭開始”創建一個新內存塊。 有趣的情況當然是input
是一個ndarray
。
在函數中使用此新數組可能會也可能不會更改原始輸入,具體取決於函數。 您必須檢查要使用的函數的文檔,以查看它是否返回副本。 NumPy開發人員努力限制不必要的副本(遵循Python示例),但有時無法避免。 文檔應該明確說明發生了什么,如果沒有或者不清楚,請提及。
如果出現問題, np.array(...)
可能會引發一些異常。 例如,嘗試使用帶有["STRING", 1]
類的輸入的dtype=float
將引發ValueError
。 但是,我必須承認我不記得在所有情況下哪些例外,請相應地編輯這篇文章 。
歡迎來到堆棧溢出。 這歸結為幾乎一種風格選擇,但我看到處理這種情況的最常見方式是將輸入轉換為數組。 Numpy為此提供了一些有用的工具。 numpy.asarray
已被提及,但這里還有一些。 numpy.at_least1d
類似於asarray
,但asarray
()數組為(1,) numpy.at_least2d
與上面相同,但重塑0d和1d數組為2d,即(3,)到(1,3)。 我們將“array_like”輸入轉換為數組的部分原因僅僅是因為我們很懶,例如有時寫foo([1, 2, 3])
比foo(numpy.array([1, 2, 3]))
更容易foo(numpy.array([1, 2, 3]))
,但這也是numpy本身的設計選擇。 請注意以下工作:
>>> numpy.mean([1., 2., 3.])
>>> 2.0
在numpy.mean
的文檔中,我們可以看到x應該是“array_like”。
Parameters ---------- a : array_like Array containing numbers whose mean is desired. If `a` is not an array, a conversion is attempted.
話雖這么說,有些情況下你只想接受數組作為參數而不是所有“array_like”類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.