Create a 2D tensor with laggged/window values from a 1D tensor time series

Hi,
Sorry for the vague question.

I have about a dozend implementations of that in numpy. So I am not looking for “one possible way to do it”.

But I know that I found somewhere on the internet ( I think it was either here or on StackOverflow) a beautiful “one liner” solution in PyTorch and thought “awesome, will try that later”. And I can’t find it again even after an hour googling or going through my history.

Problem:
given a1D tensor/array (time series) and a desired lag/window length (let’s say window length = 2)
[x1, x2, x3, x4…]

I want to get to a 2D tensor, each row the current value and the n lags:
[x1,x2,x3]
[x2,x3,x4]
[x3,x4,x5]

There are oviously many ways to do that. But I think I recall it was either a single function or maybe a clever one-line combination of reshape and other functions. But I think it was a single function call.

It drives me mad that I can’t find the particular post again. Anybody an idea?
Thanks!!

Hi Mag!

>>> import torch
>>> torch.__version__
'1.10.2'
>>> _ = torch.manual_seed (2022)
>>> n = 3
>>> t = torch.randint (100, (20,))
>>> t
tensor([41, 40, 73, 76, 49, 37, 84, 75, 24,  6, 48, 92, 37, 69, 41, 47, 75, 79,
        42, 86])
>>> t[torch.arange (n) + torch.arange (len (t) + 1 - n).unsqueeze (1)]
tensor([[41, 40, 73],
        [40, 73, 76],
        [73, 76, 49],
        [76, 49, 37],
        [49, 37, 84],
        [37, 84, 75],
        [84, 75, 24],
        [75, 24,  6],
        [24,  6, 48],
        [ 6, 48, 92],
        [48, 92, 37],
        [92, 37, 69],
        [37, 69, 41],
        [69, 41, 47],
        [41, 47, 75],
        [47, 75, 79],
        [75, 79, 42],
        [79, 42, 86]])

Best.

K. Frank

1 Like

Hi Frank,
thanks for that. That is pretty close to my numpy/torch implementations. So you don’t know of any magic function that does torch.magic(tensor, windowlength) to produce that? That is what I am looking for,.

Maybe you are thinking about unfold:

x = torch.arange(10)
y = x.unfold(dimension=0, size=3, step=1)
print(y)
# tensor([[0, 1, 2],
#         [1, 2, 3],
#         [2, 3, 4],
#         [3, 4, 5],
#         [4, 5, 6],
#         [5, 6, 7],
#         [6, 7, 8],
#         [7, 8, 9]])

or with @KFrank’s values:

torch.manual_seed(2022)
t = torch.randint (100, (20,))
print(t.unfold(dimension=0, size=3, step=1))
# tensor([[41, 40, 73],
#         [40, 73, 76],
#         [73, 76, 49],
#         [76, 49, 37],
#         [49, 37, 84],
#         [37, 84, 75],
#         [84, 75, 24],
#         [75, 24,  6],
#         [24,  6, 48],
#         [ 6, 48, 92],
#         [48, 92, 37],
#         [92, 37, 69],
#         [37, 69, 41],
#         [69, 41, 47],
#         [41, 47, 75],
#         [47, 75, 79],
#         [75, 79, 42],
#         [79, 42, 86]])
1 Like

Aahhhhhh.

You know the feeling if you hear an actors voice and can’t put a face to it, or you are humming a song and can’t really remember what song it was? And it is driving you crazy?

Thanks man. That was exactly what I was looking for, Don’t know how I missed while going through the tensor API documentation.

Thansk sooo much mate!
Regards
Phil

1 Like