pythonnumpy

Numpythonic way of the inverse of sliding_window_view


I have original array test:

from numpy.lib.stride_tricks import sliding_window_view

test = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14]).reshape(-1,7) # (batch_size, seq_len) -> (2,7)
slided = sliding_window_view(test, window_shape=(3,), axis=-1).copy()
print(test, test.shape)
print(slided, slided.shape)

Outputting:

[[ 1  2  3  4  5  6  7]
 [ 8  9 10 11 12 13 14]] (2, 7)

[[[ 1  2  3]
  [ 2  3  4]
  [ 3  4  5]
  [ 4  5  6]
  [ 5  6  7]]

 [[ 8  9 10]
  [ 9 10 11]
  [10 11 12]
  [11 12 13]
  [12 13 14]]] (2, 5, 3)

Given copied of slided array that was computed by sliding_window_view returning shape (batch_size, num_win, win_len), how do I reconstruct back into original array test with the shape of (batch_size, seq_len)?


Solution

  • Since you have a copy instead of the original sliding window view, you can't just reconstruct the shape and strides to reconstruct the original data. The copy has the wrong memory layout for that to work - the strides would have to change midway through a dimension.

    But two views of your array put together can reconstruct the original data, so if we copy two such views into a new array, we get an array equivalent to the original:

    import numpy
    
    def unslide(arr):
        shape = arr.shape[:-2] + (arr.shape[-2] + arr.shape[-1] - 1,)
        view_1 = arr[..., 0]
        view_2 = arr[..., -1, 1:]
    
        res = numpy.empty(shape=shape, dtype=arr.dtype)
        res[..., :view_1.shape[-1]] = view_1
        res[..., view_1.shape[-1]:] = view_2
    
        return res
    

    Looking at one "layer" of your array:

    [[[ 1  2  3]
      [ 2  3  4]
      [ 3  4  5]
      [ 4  5  6]
      [ 5  6  7]]
    

    we're effectively putting together the first column and last row of that layer to reconstruct that part of the original array, and doing that for every layer. view_1 handles the first column (of every layer), and view_2 handles the last row.