I want to split a matrix into arrays with different column sizes. I'm able to do it with a for loop, however I'm curious if it could be done in a faster way using some command.
Let's say for example that I have the following matrix:
matrix = [[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
[13, 14, 15, 16]]
Now I woud like to obtain a 2D-array which looks as follows:
desired_array = [[1]
[5, 6]
[9, 10, 11]
[13, 14, 15, 16]]
I want this since I would like the sum per row of the desired_array. Maybe there is another solution to obtain that sum, without using a for loop?
Thank you!
You just want the row-wise sum of the lower triangular matrix.
>>> np.tril(matrix).sum(1)
array([ 1, 11, 30, 58])
Related
So an example of the question is as follows:
Let's say we want to subdivide [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] into 3 sub-arrays.
While I imagine there are many correct answers one of them would be, [10, 8], [9, 7, 2], [1, 3, 4, 5, 6]. The reason being that here the sum of the sub arrays is, 18, 18, 19, meaning they are as close to equal as they can possibly be.
Is there an algorithm that can consistently return such an answer given any starting array and any number of sub-arrays to divide into? (Assuming that: length of the starting array > number of sub-arrays)
(PS If you want to show your logic in code I feel the most comfortable with python.)
So I was embarking on a mission to figure out how the numpy swapaxes function operates and reached a sort of a roadblock when it came to swapping axes in arrays of dimensions > 3.
Say
import numpy as np
array=np.arange(24).reshape(3,2,2,2)
This would create a numpy array of shape (3,2,2,2) with elements 0-2. Can someone explain to me how exactly axes swapping works in this case, where we cannot visualise the four axes separately?
Say I want to swap axes 0 and 2.
array.swapaxes(0,2)
It would be great if someone could actually describe the abstract swapping which is occurring when there are 4 or more axes. Thanks!
How do you 'describe' a 4d array? We don't have intuitions to match; the best we can do is project from 2d experience. rows, cols, planes, ??
This array is small enough to show the actual print:
In [271]: arr = np.arange(24).reshape(3,2,2,2)
In [272]: arr
Out[272]:
array([[[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]]],
[[[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15]]],
[[[16, 17],
[18, 19]],
[[20, 21],
[22, 23]]]])
The print marks the higher dimensions with extra [] and blank lines.
In [273]: arr.swapaxes(0,2)
Out[273]:
array([[[[ 0, 1],
[ 8, 9],
[16, 17]],
[[ 4, 5],
[12, 13],
[20, 21]]],
[[[ 2, 3],
[10, 11],
[18, 19]],
[[ 6, 7],
[14, 15],
[22, 23]]]])
To see what's actually being done, we have to look at the underlying properties of the arrays
In [274]: arr.__array_interface__
Out[274]:
{'data': (188452024, False),
'descr': [('', '<i4')],
'shape': (3, 2, 2, 2),
'strides': None, # arr.strides = (32, 16, 8, 4)
'typestr': '<i4',
'version': 3}
In [275]: arr.swapaxes(0,2).__array_interface__
Out[275]:
{'data': (188452024, False),
'descr': [('', '<i4')],
'shape': (2, 2, 3, 2),
'strides': (8, 16, 32, 4),
'typestr': '<i4',
'version': 3}
The data attributes are the same - the swap is a view, sharing data buffer with the original. So no numbers are moved around.
The shape change is obvious, that's what we told it swap. Sometimes it helps to make all dimensions different, e.g. (2,3,4)
It has also swapped 2 strides values, though how that affects the display is harder to explain. We have to know something about how shape and strides work together to create a multidimensional array (from a flat data buffer).
I'm switching from Matlab/octve to Numpy/Scipy.
To select a segment of a Matlab array, it was quite easy.
e.g.
>> x = [1, 2, 3, 4; 5, 6, 7, 8; 9, 10, 11, 12]
x =
1 2 3 4
5 6 7 8
9 10 11 12
>> y = x(2:3, 1:2)
y =
5 6
9 10
How can the same thing be done with NumPy when
x = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
As Indexing > Other indexing options in the NumPy documentation mentions,
The slicing and striding works exactly the same way it does for lists and tuples except that they can be applied to multiple dimensions as well.
For your example, this means
import numpy as np
x = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# array([[ 1, 2, 3, 4],
# [ 5, 6, 7, 8],
# [ 9, 10, 11, 12]])
x[1:3, 0:2]
# => array([[ 5, 6],
# [ 9, 10]])
Most notable difference to Matlab is probably that indexing is zero-based (i.e., first element has index 0) and that index ranges (called 'slices' in Python) are expressed with an exclusive upper bound: l[4:7] gets l[4], l[5] and l[6] (the 3rd to the 7th element), but not l[7] (the 8th element).
The Python tutorial's section on lists will give you a feeling for how indexing and slicing works for normal (1-dimensional) collections.
Suppose I have an array with 10 elements, e.g. a=np.arange(10). If I want to create another array with the 1st, 3rd, 5th, 7th, 9th, 10th elements of the original array, i.e. b=np.array([0,2,4,6,8,9]), how can I do it efficiently?
thanks
a[[0, 2, 4, 6, 8, 9]]
Index a with a list or array representing the desired indices. (Not 1, 3, 5, 7, 9, 10, because indexing starts from 0.) It's a bit confusing that the indices and the values are the same here, so have a different example:
>>> a = np.array([5, 4, 6, 3, 7, 2, 8, 1, 9, 0])
>>> a[[0, 2, 4, 6, 8, 9]]
array([5, 6, 7, 8, 9, 0])
Note that this creates a copy, not a view. Also, note that this might not generalize to multiple axes the way you expect.
How do I generate all possible permutations of a list of numbers in C?
As an example, [1, 8, 12] would generate
[1, 12, 8],
[12, 8, 1],
[12, 1, 8], ...
Have a look at this Johnson-Trotter Algorithm and applet it is exactly what you want.