заполнение пустых шагов с левой и правой стороны

Я написал (с небольшой помощью от SO) функцию для извлечения скользящих окон с перекрытием L из серии a, заполняя fillval либо справа, либо слева, когда L/(L-перекрытие) не является целым числом, используя шаги numpy:

def strided_axis0_overlap(a, fillval, L,overlap,pad='left'): # a is 1D array
    assert(overlap<L)
    if pad=='left':
        a_ext = np.concatenate(( np.full(L-1,fillval) ,a))
    elif pad=='right':
        a_ext = np.concatenate((a,np.full(L-1,fillval)))  
    n = a_ext.strides[0]
    strided = np.lib.stride_tricks.as_strided   
    if pad=='left':
        return strided(a_ext, shape=(a.shape[0],L), strides=(n,n))[[np.arange(0,len(a),L-overlap)],:]  
    elif pad=='right':
        return strided(a_ext, shape=(a.shape[0],L), strides=(n,n))[[np.arange(0,len(a),L-overlap)],:]

Он отлично работает, кроме этого для заполнения. Если я сделаю

 v=np.array(range(182)).T
 strided_axis0_overlap(v,np.nan,5*6,0,pad='right')

Я получаю следующее, что ожидается:

array([[[   0.,    1.,    2., ...,   27.,   28.,   29.],
        [  30.,   31.,   32., ...,   57.,   58.,   59.],
        [  60.,   61.,   62., ...,   87.,   88.,   89.],
        ..., 
        [ 120.,  121.,  122., ...,  147.,  148.,  149.],
        [ 150.,  151.,  152., ...,  177.,  178.,  179.],
    [ 180.,  181.,   nan, ...,   nan,   nan,   nan]]])

Однако, если я положу слева

array([[[  nan,   nan,   nan, ...,   nan,   nan,    0.],
        [   1.,    2.,    3., ...,   28.,   29.,   30.],
        [  31.,   32.,   33., ...,   58.,   59.,   60.],
        ..., 
        [  91.,   92.,   93., ...,  118.,  119.,  120.],
        [ 121.,  122.,  123., ...,  148.,  149.,  150.],
        [ 151.,  152.,  153., ...,  178.,  179.,  180.]]])

тогда как я хотел, чтобы последнее окно заканчивалось на 182, а первое было похоже на массив ([[[ nan, nan, nan, ..., nan, 0, 1.],


person 00__00__00    schedule 26.01.2018    source источник


Ответы (1)


Вы всегда дополняете L - 1 элементов. Это слишком много в обязательных случаях, но в случае заполнения справа это не имеет значения, потому что лишние элементы конца массива игнорируются. Однако в случае заполнения слева это заметно, потому что все элементы с начала попадают в массив.

В конкретном случае вы вставляете 29 элементов, но вам нужно только 28, поэтому последний элемент в массиве удаляется из скользящего окна.

Количество вставляемых элементов должно зависеть как от размера массива, так и от размера окна:

L - (a.shape[0] - 1) % L - 1

Это будет оцениваться как количество элементов, необходимых для того, чтобы сделать размер массива целым числом, кратным размеру окна (который может быть равен 0, если они уже совпадают).

person kazemakase    schedule 26.01.2018