Rangooski
Rangooski

Reputation: 873

Python : Numpy Matrix split

I have a matrix of shape 4 x 129. I am trying to do a horizontal split like the example shown below:

In [18]: x = np.arange(4*129)

In [19]: x = x.reshape(4, 129)

In [20]: x.shape
Out[20]: (4, 129)

In [21]: y = np.hsplit(x, 13)

ValueError: array split does not result in an equal division

I understand that it can't split it equally into 13. I don't want to do zero pad one more column and divide by 13.

I want to split the x matrix into 13 small matrices, where the each 12 split should be in size of 4 x 10 and the last one should be in size of 4 x 9.

Is there any way to do like this ?

Upvotes: 4

Views: 1680

Answers (3)

Daksh Gupta
Daksh Gupta

Reputation: 7804

To have multiple splits, we can pass a list of indexes depicting the position where it needs to be splited. For example

arr = np.array([1,2,3,4,5,6,7,8,9,10])

# we want to split at Index 3,6,8, so we'll use split as

split_arr = np.split(arr, [3,6,8])

The split means that it will slice as follows

1. arr [0:3]  # Index - > 0,1,2
2. arr [3:6]  # Index -> 3,4,5,
3. arr [6:8]  # Index -> 6,7
4. arr [8:]   # Index -> 8...end

You can also reshape the individual split as

split_arr.reshape(3,1)

In the example above, Lets suppose we have only 129 elements ( not multiplying by 4 for simplicity), the split can be.

new_arr = np.split(arr, [13,26,39,52,65,78,91,104,117] )

On 1-D arrays, both split and hsplit works in similar way.

Hope it helps

Upvotes: 1

HolyDanna
HolyDanna

Reputation: 629

I do not know how to do it using np.hsplit with an int as second parameter, but while looking around, I found a way to do it using an array, as a parameter.

The way to do it would be :

temp_array = [(i+1)*10 for i in range((129-1)//10)]
y = np.hsplit(x,temp_array)

or in one line :

y = np.hsplit(x,[(i+1)*10 for i in range((129-1)//10)])

Edit : added -1 while creating the array, to prevent the creation of an empty array at the end of x when the size of the original array is a multiple of the size of the sub-array we want;

Edit2 : another way to create the temp_array is

temp_array = np.arange(10,129,10)

Putting everything in one line :

y = np.hsplit(x,np.arange(10,129,10))

Edit3 : Found out there was a problem using python3 (was testing using python2) : the result from an int division can be a float. Use // instead of /for the division, to ensure the result is an int

Explanation : I create an array ('splitting_array') with every multiple of the size of the sub-array I want strictly between 0 and the size of the original array.
I then split the original array using the 'splitting_array'. According to the doc for numpy.split, it will split the original_array along the horizontal axis at the indexes given by 'splitting_array'.
So, in our case, the original_array will be split before every index that is a multiple of 10.

Upvotes: 2

Kasravnd
Kasravnd

Reputation: 107287

You can pass the indices for split and in this case you can create them simply using np.arange():

>>> a = np.hsplit(x, np.arange(12, 129, 12))
>>> 
>>> a[0].shape
(4, 12)
>>> a[-1].shape
(4, 9)

Upvotes: 5

Related Questions