How to reorder the matrix [duplicate] - python

This question already has answers here:
What is the best way to perform an anti-transpose in python?
(4 answers)
Closed 4 months ago.
Does anyone could tell me how to reorder the matrix:
[[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]]
To:
[[15, 10, 5],
[14, 9, 4],
[13, 8, 3],
[12, 7, 2],
[11, 6, 1]]

Since you have tagged the question numpy, I surmise that those are numpy matrix, and you are looking for a numpy solution (otherwise, if those are lists, Ann's zip is the correct solution).
For numpy you can
M[::-1,::-1].T
Example
M=np.array([[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]])
M[::-1,::-1].T
returns
array([[15, 10, 5],
[14, 9, 4],
[13, 8, 3],
[12, 7, 2],
[11, 6, 1]])
as expected

I'd suggest using numpy, like so:
import numpy as np
matrix = np.array([[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]])
transformed_matrix = matrix[::-1].T[::-1]
# array([[15, 10, 5],
# [14, 9, 4],
# [13, 8, 3],
# [12, 7, 2],
# [11, 6, 1]])
matrix[::-1] gives you the original matrix in reverse order (i.e. [11, 12, 13...] first and [1, 2, 3...] last).
Taking the transpose of that with .T rotates the matrix about - swapping rows and columns.
Lastly, indexing the transpose with [::-1] reverses the order, putting [15, 14, 13...] first and [5, 4, 3...] last.

Here is how you can use the zip() method to transpose your matrix:
m = [[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]]
print([list(i)[::-1] for i in zip(*m)][::-1])
Output:
[[15, 10, 5],
[14, 9, 4],
[13, 8, 3],
[12, 7, 2],
[11, 6, 1]]
The index [::-1] reverses the array.

Related

How to make a 2d numpy array from an empty numpy array by adding 1d numpy arrays?

So I'm trying to start an empty numpy array with a = np.array([]), but when i append other numpy arrays (like [1, 2, 3, 4, 5, 6, 7, 8] and [9, 10, 11, 12, 13, 14, 15, 16] to this array, then the result im basically getting is
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16].
But what i want as result is: [[1, 2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16]]
IIUC you want to keep adding lists to your np.array. In that case, you can use something like np.vstack to "append" the new lists to the array.
a = np.array([[1, 2, 3],[4, 5, 6]])
np.vstack([a, [7, 8, 9]])
>>> array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
You can also use np.c_[], especially if a and b are already 1D arrays (but it also works with lists):
a = [1, 2, 3, 4, 5, 6, 7, 8]
b = [9, 10, 11, 12, 13, 14, 15, 16]
>>> np.c_[a, b]
array([[ 1, 9],
[ 2, 10],
[ 3, 11],
[ 4, 12],
[ 5, 13],
[ 6, 14],
[ 7, 15],
[ 8, 16]])
It also works "multiple times":
>>> np.c_[np.c_[a, b], a, b]
array([[ 1, 9, 1, 9],
[ 2, 10, 2, 10],
[ 3, 11, 3, 11],
[ 4, 12, 4, 12],
[ 5, 13, 5, 13],
[ 6, 14, 6, 14],
[ 7, 15, 7, 15],
[ 8, 16, 8, 16]])

Numpy selecting specific columns from each row

I have matrix A of shape (p, q, r, r) and another matrix I of shape (r, s). I want to select only s of the r elements from the last dimension of A, so that the shape of the new matrix becomes (p, q, r, s).
To simplify (ignoring the first two dimensions), let
>>> A
array([[5, 2, 5, 7],
[2, 6, 4, 3],
[4, 2, 3, 9],
[6, 2, 4, 3]])
>>> I
array([[1, 2],
[2, 2],
[3, 1],
[2, 1]])
I want the matrix
array([[2, 5],
[4, 4],
[9, 2],
[4, 2]])
How can I do it? A[..., I] gives a (4, 4, 2) matrix, selecting elements located at I from each row. I can solve the problem by
>>> c = np.arange(4)
>>> A[..., I][c, c, :]
array([[2, 5],
[4, 4],
[9, 2],
[4, 2]])
But I think it requires a lot of computation. Is there any more efficient way to solve this issue?
Edit:
For higher dimensional example, consider I to be same as before, and
A
array([[[[12, 15, 6, 12],
[16, 16, 4, 17],
[ 6, 19, 10, 9],
[ 5, 11, 18, 17]],
[[13, 12, 5, 6],
[12, 7, 5, 4],
[ 9, 19, 12, 4],
[15, 4, 16, 7]],
[[13, 6, 5, 17],
[ 8, 4, 10, 9],
[ 3, 13, 16, 4],
[ 3, 3, 4, 4]]],
[[[ 8, 3, 8, 18],
[ 7, 11, 8, 7],
[10, 8, 14, 9],
[ 8, 12, 16, 5]],
[[ 9, 10, 10, 7],
[11, 6, 10, 6],
[16, 19, 10, 14],
[ 9, 13, 13, 19]],
[[10, 8, 19, 12],
[ 9, 10, 17, 19],
[ 4, 11, 12, 14],
[ 8, 5, 16, 10]]]])
Expected output:
array([[[[15, 6],
[ 4, 4],
[ 9, 19],
[18, 11]],
[[12, 5],
[ 5, 5],
[ 4, 19],
[16, 4]],
[[ 6, 5],
[10, 10],
[ 4, 13],
[ 4, 3]]],
[[[ 3, 8],
[ 8, 8],
[ 9, 8],
[16, 12]],
[[10, 10],
[10, 10],
[14, 19],
[13, 13]],
[[ 8, 19],
[17, 17],
[14, 11],
[16, 5]]]]
A[...,I][..., c, c, :] yield this result
Since you're using integer array indexing, you'll need to specify which rows you want to select those columns from:
A[np.arange(A.shape[0])[:,None], I]
array([[2, 5],
[4, 4],
[9, 2],
[4, 2]])
Or you also have np.take_along_axis:
np.take_along_axis(A, I, 1)
For a larger array of shape (p, q, r, r), take full slices along the front axes, and use broadcasting in a similar way:
A[...,np.arange(A.shape[2])[:,None],I]
array([[[[15, 6],
[ 4, 4],
[ 9, 19],
[18, 11]],
[[12, 5],
[ 5, 5],
[ 4, 19],
[16, 4]],
...

Conditional merging of sublists in a list

I have the following list of lists.
If last sublist has len>1:
x = [[0], [1, 2, 3], [4, 5], [6], [7, 8, 9], [10, 11, 12, 13], [15], [16, 17, 18]]
expected_output = [[0, 1, 2, 3], [4, 5], [6, 7, 8, 9], [10, 11, 12, 13], [15, 16, 17, 18]]
If last sublist has len==1:
x = [[0], [1, 2, 3], [4, 5], [6], [7, 8, 9], [10, 11, 12, 13], [15], [16, 17, 18], [19]]
expected_output = [[0, 1, 2, 3], [4, 5], [6, 7, 8, 9], [10, 11, 12, 13], [15, 16, 17, 18], [19]]
I'm trying to merge the sublists of length 1 with the next sublist.
If the last sublist length is one, I want to leave it as is.
I tried writing the following code.
xt = []
for i in range(len(x)-1):
if len(x[i]) == 1:
xt.append(x[i]+x[i+1])
# del x[i+1]
if len(x[i])>1:
xt.append(x[i])
print(xt)
Try this :
def ref1(l):
con = 0
l2 = []
while con<len(l)-1:
if len(l[con])==1:
l2.append(l[con]+l[con+1])
con +=2
else:
l2.append(l[con])
con+=1
if len(l[-1])==1:
l2.append(l[-1])
print(l2)
ref1([[0], [1, 2, 3], [4, 5], [6], [7, 8, 9], [10, 11, 12, 13], [15], [16, 17, 18]])
# OUTPUT : [[0, 1, 2, 3], [4, 5], [6, 7, 8, 9], [10, 11, 12, 13], [15, 16, 17, 18]]
ref1([[0], [1, 2, 3], [4, 5], [6], [7, 8, 9], [10, 11, 12, 13], [15], [16, 17, 18], [19]])
# OUTPUT : [[0, 1, 2, 3], [4, 5], [6, 7, 8, 9], [10, 11, 12, 13], [15, 16, 17, 18], [19]]
Code Analysis
xt = []
for i in range(len(x)-1):
if len(x[i]) == 1:
xt.append(x[i]+x[i+1])
This means you are adding the next sublist before visiting it
# del x[i+1]
if len(x[i])>1:
xt.append(x[i])
and this doesn't have a history of if the sublist has already been merged.
print(xt)
Advice
Visit the list the other way around, and check each time if the previous list is of length 1.
OR
Keep tab of if the previous action was a merge.
TO OP
If you need more help, please shout

Slice array, but overlapped interval in Python

There are 3D-array in my data. I just want to slice 3D-array 2 by 2 by 2 with overlapped interval in Python.
Here is an example for 2D.
a = [1, 2, 3, 4;
5, 6, 7, 8]
Also, this is what I expected after slicing the array in 2 by 2.
[1, 2; [2, 3; [3, 4;
5, 6] 6, 7] 7, 8]
In 3D,
[[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]]
Like this,(maybe not exactly..)
[1, 2 [2, 3
4, 5] 5, 6] ...
[1, 2 [2, 3
4, 5] 5, 6]
I think, by using np.split, I could slice the array, but without overlapped. Please give me some helpful tips.
You should have a look at numpy.ndarray.strides and numpy.lib.stride_tricks
Tuple of bytes to step in each dimension when traversing an array.
The byte offset of element (i[0], i[1], ..., i[n]) in an array a is:
offset = sum(np.array(i) * a.strides)
See also the numpy documentation
Following a 2D example using strides:
x = np.arange(20).reshape([4, 5])
>>> x
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
>>> from numpy.lib import stride_tricks
>>> stride_tricks.as_strided(x, shape=(3, 2, 5),
strides=(20, 20, 4))
...
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9]],
[[ 5, 6, 7, 8, 9],
[ 10, 11, 12, 13, 14]],
[[ 10, 11, 12, 13, 14],
[ 15, 16, 17, 18, 19]]])
Also see this question on Stackoverflow, where this example is from, to increase your understanding.

python display remaining values after dividing the matrix

i = [1,2,3,4,5,6,7,8,9,10]
def ndiv(l,n):
return [l[s:e] for s, e in zip(range(0,len(l)+1,n),xrange(n,len(l)+1,n))]
for i in xrange(1,15,1):
print "CLUSTER {}".format((ndiv(l,i)))
#print
CLUSTER [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17]]
CLUSTER [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16]]
CLUSTER [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]
CLUSTER [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
CLUSTER [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]]
CLUSTER [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
CLUSTER [[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14]]
CLUSTER [[1, 2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16]]
CLUSTER [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
Coding up to now. After dividing, the remaining values are not shown omitted.But I want to have the prices shown after we split them(EX.if divide '3' ->before [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]] / after [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15],[16],[17] ).How can I divide and then show the remaining numbers one by one?
You can compute 2 lists, one that splits contains batches of n and the other that maps remaining elements into one element list and finally merge them together
>>> l = list(xrange(1,18))
>>> def ndiv(l,n):
... return [l[i:i+n] for i in xrange(0,len(l)//n*n, n)] + [[e] for e in l[len(l)//n*n:]]
...
>>> ndiv(l, 5)
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16], [17]]

Categories