2017-08-15 31 views
11

numpy.lib.stride_tricks.as_strided的結果是否取決於NumPy數組的dtype?numpy.as_strided的結果是否取決於輸入dtype?

這個問題源於的.strides定義,這是字節遍歷一個數組的,則進入步驟在每個維度上的

元組。

以下是我在其他問題中使用的以下函數。它需要一個1d或2d陣列並創建長度爲window的重疊窗口。結果會比輸入大一個維度。

def rwindows(a, window): 
    if a.ndim == 1: 
     a = a.reshape(-1, 1) 
    shape = a.shape[0] - window + 1, window, a.shape[-1] 
    strides = (a.strides[0],) + a.strides 
    windows = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides) 
    return np.squeeze(windows) 

# examples 
# rwindows(np.arange(5), window=2) 
# rwindows(np.arange(20).reshape((5,4)), window=2) 

因爲進步的定義,因爲,例如,否則相當於D型float32float64的陣列都會有不同的進展,將這個不斷炸燬我rwindows功能上面?

我試過測試,但它是以非窮舉的方式,並且正在尋找一個答案,(1)解釋函數doc中的免責聲明/警告是否與我在這裏提出的問題有關和(2)解釋了爲什麼或者爲什麼沒有其他等效陣列具有不同的dtype &步長會在上述中產生不同的結果。

+3

我見過兩個問題。如果形狀不正確,則可以在緩衝區末尾「跨越」。沒有保證確保所有索引值都是有效的。其次,跨步陣列上的許多操作都會複製。該副本可能比原始數組或大視圖大得多;對於多維跨步(2或3d窗口)更是如此。 – hpaulj

+0

呵呵。看起來這個功能已經足夠流行,現在他們正在記錄它。 – user2357112

回答

4

不,as_strided的警告是針對兩個與數據大小無關的問題,以及寫入結果視圖的更多結果。

  1. 首先,沒有任何保護措施,以保證在aview = as_strided(a . . .)指向的內存。這就是爲什麼在致電as_strided之前進行了如此多的精心準備工作。如果算法關閉,您可以輕鬆地將您的view指向不在a中的內存,並且可能確實將其指向垃圾,其他變量或操作系統。如果您隨後寫入該視圖,您的數據可能會丟失,錯位,損壞。 。 。或者使你的電腦崩潰。

對於您的具體示例,它的安全性很大程度上取決於您使用的輸入。您已將stridesa.strides設置爲動態。你可能想要assertadtype是不是像object奇怪。

如果你確定,你將永遠 2 d awindow大,你可能會被罰款與你的算法,但你也可以assert,要確保。否則,您可能需要確保as_strided輸出適用於n-d a陣列。例如:

shape = a.shape[0] - window + 1, window, a.shape[-1] 

或許應該

shape = (a.shape[0] - window + 1, window) + a.shape[1:] 

才能接受正d輸入。它會可能至於引用錯誤的內存從來沒有問題,但目前的shape將引用a中的錯誤數據,如果你有更多的尺寸。

  1. 其次,創建的視圖多次引用相同的數據塊。如果您然後對該視圖執行並行寫入(通過view = foobar(. . ., out = view)),則結果可能爲unpredictable,可能與您的預期不符。

這就是說,如果你害怕的問題,並且不需要寫as_strided視圖(如你對於它是常用的大多數卷積應用程序不),你總是可以將其設置爲writable = False ,即使您的strides和/或shape不正確,這也可以防止這兩個問題。

編輯:正如指出的@hpaulj,除了這兩個問題,如果你做的東西到view,使一個副本(如.flatten()或花哨的索引一大塊的話),它可以引起MemoryError