簡體   English   中英

numpy:將多個切片組裝成新的數組

[英]numpy : assembling multiple slices into new array

我有一個二維數組,我需要將部分(切片)提取到一個新數組中:

original= numpy.ndarray( shape=(4,4) )
slices= numpy.ndarray( shape=(0,2) )
for x in range(3):
    slice= original[x:x+2,x:x+2] 
    slices=numpy.append(slices, slice,axis=0)

有沒有更有效的方法來做到這一點(擺脫python循環)?

- - 編輯 - -

為了澄清,我問如何將任意(但類似)形狀的2D切片從2D陣列的任意2D索引復制到另一個垂直堆疊 - 特別是沿對角線或2x2大小。

stride_tricks有一個漂亮的技巧,你可以在SO和其他方面找到具有不同通用性的滾動窗口函數(目前numpy本身沒有),這里是根據你得到的版本量身定制的:

def rolling_window(arr, window):
    """Very basic multi dimensional rolling window. window should be the shape of
    of the desired subarrays. Window is either a scalar or a tuple of same size
    as `arr.shape`.
    """
    shape = np.array(arr.shape*2)
    strides = np.array(arr.strides*2)
    window = np.asarray(window)
    shape[arr.ndim:] = window # new dimensions size
    shape[:arr.ndim] -= window - 1
    if np.any(shape < 1):
        raise ValueError('window size is too large')
    return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)

# Now:
view = rolling_window(arr, 2)
view[0,0] # first slice in your loop

請注意, view包含與原始數組相同的數據! 這可能會導致意外結果。 但是你似乎只想要對角線,你也可以用大步技巧來做到這一點,以確保你不要復制數據(下一版本將創建一個帶有diagonal的視圖,舊版本總是一個副本):

diagonal = np.diagonal(view, axis1=0, axis2=1)
# unfortunatly now the first slice is diagonal[...,0], so just roll it to the start:
diagonal = np.rollaxis(diagonal, -1)

現在, diagonal是您在for循環中創建的數組.copy()如果您不想要視圖,則在較新版本上添加.copy() )。

編輯:由於slices數組是2D而不是3D因為你追加,所以這里缺少一個重塑:

slices = diagonal.reshape(-1,2)

如果你有這么小的數組,但它的常量(期望在diagonal調用中復制數據)與數組大小相比,這可能不會更快。

這是你的解決方案:

v = np.arange(0,original.shape[0],0.5).astype(int)
result = np.c_[ original[v[1:-1],v[:-2]] , original[v[1:-1],v[2:]] ]

適用於任何大小的方形輸入矩陣(您稱之為“原始”)。

想法是創建一個“輔助數組”v,簡單地是[0,0,1,1,2,2,3,3,...],然后使用觀察,你需要的索引總是很簡單切片v。

請享用!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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