Somthin
Somthin

Reputation: 73

Split array into equal sized windows

I am trying to split an numpy.array of length 40 into smaller, equal-sized numpy.arrays, in which the number of the smaller arrays is given by the user. It is allowed to have some overlap between the smaller arrays, as situations can occur where the full length is only divisible by the splits given some form of overlap of the smaller arrays.

If I had an array np.array([range(40)]) And I had to split it into 37 sub arrays, the list of subarrays should be like this:

[1, 2, 3], [3, 4, 5], [5, 6, 7], ... [38, 39, 40]

I tried using numpy.split but this only works when the length is divisible by the size, and numpy.array_split generates uneven sizes.

Example using numpy.split

>> import numpy as np
>>> a = np.random.randint(6,size=(40))
>>> b = np.split(a,37)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/numpy/lib/shape_base.py", line 508, in split
    'array split does not result in an equal division')
ValueError: array split does not result in an equal division

And with numpy.array_split

>>> a = np.random.randint(5,size=(40))
>>> b = np.array_split(a,37)
>>> print len(b)
37
>>> print b[0].shape
(2,)
>>> print b[3].shape
(1,)
>>> print b[5].shape
(1,)
>>> print b[6].shape
(1,)
>>> print b[30].shape
(1,)
>>> 

numpy.array_split don't equally divide them.

Any solution?

Upvotes: 7

Views: 10783

Answers (3)

Walid Bousseta
Walid Bousseta

Reputation: 1469

this is another way if you want to split the array with a windowing size

from numpy.lib.stride_tricks import sliding_window_view

def unfold(array, size, step):
    """
    params:
       array: 1d array 
       size : size of each chunk
       step : windowing size
    """
    assert array.ndim == 1, f"Not implemented yet, expecting 1d array but got {array.ndim}d"
    return sliding_window_view(array, window_shape=size)[::step]

find more here

Upvotes: 0

Arya McCarthy
Arya McCarthy

Reputation: 8829

What you're describing is called a (sliding) window, not a split.

See this answer: https://stackoverflow.com/a/15722507/7802200

What you want is to use the window_stack function developed there with a width of len(a) - n_splits + 1.

Upvotes: 3

Matthew Ciaramitaro
Matthew Ciaramitaro

Reputation: 1179

numpy.split() should generate equal sized sub arrays of exactly the size specified in the parameter indices_or_sections which is the second input of the function. How have you tried using the split functions? If you want to split the array arrinto 4 subarrays of size 5, use

numpy.split(arr,4)

The reason your example failed is that the array size must be divisible by the number of arrays you want. Which makes sense, because you can only split into equal sizes when the number of elements divided by the number of subarrays is an integer.

Now that you've clarified your question, I think there is no simple solution. It is easy to divide the array into equally sized groups, but if the user requests 37 equally sized groups from a set of 40 with overlap allowed, there is more than one way to do this, and you have not given us criteria to determine such methods as to help you. There won't be any easy numpy function for the task you are looking for, you'll need a search algorithm (DFS?) to figure out how to divide the set into 37 (or whatever is requested) equally sized groups.

Upvotes: 0

Related Questions