Раздвижные окна из двумерного массива, который скользит вдоль оси = 0, чтобы получить трехмерный массив с динамическим перекрытием

1

Используя ответ из этого вопроса, я могу получить оконную версию матрицы по строкам с stride = 1 (каждое окно остается тем же, за исключением строки):

def strided_axis0(a, L): 
   nd0 = a.shape[0] - L + 1
   m,n = a.shape
   s0,s1 = a.strides
   return np.lib.stride_tricks.as_strided(a, shape=(nd0,L,n), strides=(s0,s0,s1))

Я хотел бы иметь параметр в функции для получения различного перекрытия.

Например:

In [49]: X
Out[49]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24],
       [25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34],
       [35, 36, 37, 38, 39]])

In [50]: strided_axis0(X, L=4, ov = 2)

Out[50]: 
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]],

       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29]],


       [[20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34],
        [35, 36, 37, 38, 39]]])
Теги:
numpy
python-3.x

2 ответа

1
Лучший ответ

Здесь версия с np.lib.stride_tricks.as_strided -

import warnings

def strided_axis0(a, L, overlap=1):
    if L==overlap:
        raise Exception("Overlap arg must be smaller than length of windows")
    S = L - overlap
    nd0 = ((len(a)-L)//S)+1
    if nd0*S-S!=len(a)-L:
        warnings.warn("Not all elements were covered")
    m,n = a.shape
    s0,s1 = a.strides
    return np.lib.stride_tricks.as_strided(a, shape=(nd0,L,n), strides=(S*s0,s0,s1))

Мы также можем использовать np.lib.stride_tricks.as_strided основе scikit-image view_as_windows чтобы получить раздвижные окна. Дополнительная информация об использовании as_strided основе view_as_windows.

from skimage.util.shape import view_as_windows

def strided_axis0(a, L, overlap=1):
    if L==overlap:
        raise Exception("Overlap arg must be smaller than length of windows")
    S = L - overlap
    nd0 = ((len(a)-L)//S)+1
    if nd0*S-S!=len(a)-L:
        warnings.warn("Not all elements were covered")
    return view_as_windows(a, (L,a.shape[1]), step=S)[:,0,:,:]
  • 0
    идеальный! Две реализации равны, верно?
1

Вы можете попробовать:

def get_strides(a, L, ov):
    out = []
    for i in range(0, a.shape[0]-L+1, L-ov):
        out.append(a[i:i+L, :])

    return np.array(out)

В принципе, он генерирует весь массив, начиная с строки 0 и перемещаясь вниз по строкам L-ov. Он останавливается, когда он находится на расстоянии L от конца массива. Предоставляя массив в качестве входных данных, он производит:

> print(get_strides(a, 4, 2))
> [[[ 0  1  2  3  4]
    [ 5  6  7  8  9]
    [10 11 12 13 14]
    [15 16 17 18 19]]

  [[10 11 12 13 14]
    [15 16 17 18 19]
    [20 21 22 23 24]
    [25 26 27 28 29]]

  [[20 21 22 23 24]
    [25 26 27 28 29]
    [30 31 32 33 34]
    [35 36 37 38 39]]]
  • 0
    да, я уже сделал это, но для больших матриц это становится очень медленным. Спасибо, в любом случае

Ещё вопросы

Сообщество Overcoder
Наверх
Меню