The use of np.matrix is discouraged, if not actually deprecated. It is rarely needed, except for some backward compatibility cases.
In [1]: arr = np.zeros((5,5))
In [2]: arr
Out[2]:
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
In [3]: mat = np.matrix(arr)
In [4]: mat
Out[4]:
matrix([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
Indexing one row of arr produces a 1d array
In [5]: arr[2]
Out[5]: array([0., 0., 0., 0., 0.])
Indexing one row of mat produces a 2d matrix, with shape (1,5)
In [6]: mat[2]
Out[6]: matrix([[0., 0., 0., 0., 0.]])
We can access an element in the 1d array:
In [7]: arr[2][1]
Out[7]: 0.0
but this indexing of the mat tries to access a row, and gives an error:
In [8]: mat[2][1]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-8-212ad5378f8e> in <module>
----> 1 mat[2][1]
...
IndexError: index 1 is out of bounds for axis 0 with size 1
In both cases it is better to access an element with the tuple syntax, rather than the chained one:
In [9]: arr[2,1]
Out[9]: 0.0
In [10]: mat[2,1]
Out[10]: 0.0
This indexing also works for setting values. But try to avoid iterating to set individual values. Try to find ways of creating the whole array with the desired values directly, with whole array methods, not iteration.
my_matrix[2] = 10, Then it would replace all the elements in the 3rd row (row with index2).my_matrix[2][1] = 10, Then it would replace only the element in 3rd row (row index2) and 2nd column (column index1)my_matrix[2, 1] = 10. Or, for a minor performance improvement if you are going to be setting lots of individual elements:my_matrix.itemset((2, 1), 10)