I have a collection of (6 by 6)
matrices, In my code, I may get 5 to 6 matrices (of order (6 by 6).)
I wanted to delete certain rows
and columns
in each of these 5 to 6 matrices I have.
so I ran a for-loop
suppose for now, in that collection I have only "one" matrix (a_matrix
of order 6 by 6
).
Each matrix that comes into this for-loop
should get reduced to 2 by 2 matrices
shown below. (desired output)
this is my failed attempt, here a_matrix
will not work as there is only a single 6 by 6
matrix in my collection.
it is showing an error as
ValueError: could not broadcast input array from shape (5) into shape (6)
import numpy as np
a_matrix = np.array ( [ [ 1, 2, 3, 4, 5, 6 ],
[ 7, 8, 9, 10, 11, 12 ],
[ 13, 14, 15, 16, 17, 18 ],
[ 19, 20, 21, 22, 23, 24 ],
[ 25, 26, 27, 28, 29, 30 ],
[ 31, 32, 33, 34, 35, 36 ]] )
total_no_of_matrices = 1
for i in range(total_no_of_matrices):
a_matrix[i] = np.delete(a_matrix[i], 0, 0)
a_matrix[i] = np.delete(a_matrix[i], 0, 0)
a_matrix[i] = np.delete(a_matrix[i], 1, 0)
a_matrix[i] = np.delete(a_matrix[i], 1, 0)
print(a_matrix)
desired output- (after deletion of certain rows and columns)
a_matrix = [[15, 18],
[33, 36]]
CodePudding user response:
The issue is that numpy makes arrays as static as possible. So, if you declare an array to be nx6x6 you can't suddenly tell it that you want matrix 3 to be 2x2. The better way is to declare a new array that will hold the smaller matrices. There are some cases where you can make a numpy array dynamic, but it is usually very inefficient and usually you preallocate the arrays anyway -- if you can't, a numpy array is probably not the right object to use. Here's how I might approach this:
import numpy as np
a_matrix = np.arange(1, 6 * 6 1).reshape((6, 6))
if a_matrix.ndim == 2:
a_matrix = a_matrix.reshape((1, a_matrix.shape[0], a_matrix.shape[1]))
total_no_of_matrices = a_matrix.shape[0]
reduced_matrices = np.zeros((total_no_of_matrices, 2, 2))
rows_to_delete = [0, 1, 3, 4]
cols_to_delete = [0, 1, 3, 4]
for i in range(total_no_of_matrices):
temp_matrix = np.delete(a_matrix[i, :, :], rows_to_delete, axis=0)
temp_matrix = np.delete(temp_matrix, cols_to_delete, axis=1)
reduced_matrices[i, :, :] = temp_matrix
print(a_matrix)
print(reduced_matrices)
Also, if you want to get really fancy, you can use advanced indexing. But sometimes I find it hard to follow, and I use numpy all the time. So if anyone reads the code maybe stay away from it, but here is another option
another_way = a_matrix[:, np.array([[2, 2], [5, 5]]), np.array([[2, 5], [2, 5]])]
print(another_way)
CodePudding user response:
Say you have 20 such matrices, so (20,6,6)
is their shape. You can use indexing like matrices[:, 2:6:3, 2:6:3]
to get all 2 x 2 reduced matrices.
import numpy as np
matrices = np.arange(1, 20*6*6 1).reshape((20, 6, 6))
reduced_matrices = matrices[:, 2:6:3, 2:6:3]
See the first one for example:
reduced_matrices[0]
[[15 18]
[33 36]]
If you like using loops, then a simple comprehension could do the same as well:
reduced_matrices = [ m[2:6:3,2:6:3] for m in matrices ]