Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select a sliding window of elements from a list of lists?

Say I have the following list of lists:

x = [[1,2,3],[4,5,6],[7,8,9,10]]

And I wish to select all 'windows' of size e.g. n=4, staggered by a distance of e.g. d=2:

    [[1,2,3],[4]]                # Starts at position `0`
        [[3],[4,5,6]]            # Starts at position `d`
              [[5,6],[7,8]]      # Starts at position `2d`
                    [[7,8,9,10]] # Starts at position `3d`

I.e. I wish to take intersecting 'slices' where the windows overlap with the sublists.

How would I go about this?

like image 836
iacob Avatar asked Jan 27 '23 08:01

iacob


1 Answers

If you precompute some indices, you can reconstruct any window with a virtual one-liner:

import itertools
import operator

def window(x, start, stop):
    first = indices[start][0]
    last = indices[stop-1][0]
    return [
        [x[i][j] for i, j in g] if k in (first, last) else x[k]
        for k, g in itertools.groupby(
            indices[start:stop],
            key=operator.itemgetter(0))
        ]

def flat_len(x):
    """Return length of flattened list."""
    return sum(len(sublist) for sublist in x)
n=4; d=2
x = [[1,2,3],[4,5,6],[7,8,9,10]]

indices = [(i, j) for i, sublist in enumerate(x) for j in range(len(sublist))]

for i in range(0,flat_len(x)-n+1,d):
    print(window(x,i,i+n,indices))

>>> [[1, 2, 3], [4]]
>>> [[3], [4, 5, 6]]
>>> [[5, 6], [7, 8]]
like image 76
VPfB Avatar answered Jan 31 '23 10:01

VPfB