簡體   English   中英

使用ndim對ndarray進行Python-numpy測試

[英]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.asarraynp.asanyarraynp.atleast_1D ......都是更通用的函數np.array 例如, asarrayarray的可選copy參數設置為Falseasanyarray設置相同並設置subok=Trueatleast_1D設置ndmin=1atleast_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM