Reputation: 141
I'm having problems with the following task.
Assume we have a matrix, looking like this:
Mat = np.array([
[11, 12, 13, 14, 15], \
[21, 22, 23, 24, 25], \
[31, 32, 33, 34, 35], \
[41, 42, 43, 44, 45], \
[51, 52, 53, 54, 55]])
What I want to do is to replace the entries 22, 33 and 44 with something different that I calculated before. I know I could do this with for loops but I think there has to be a more elegant way.
I have something like this in mind:
I found the np.diagonal() to get the diagonal and got so far:
Mat = np.array([
[11, 12, 13, 14, 15], \
[21, 22, 23, 24, 25], \
[31, 32, 33, 34, 35], \
[41, 42, 43, 44, 45], \
[51, 52, 53, 54, 55]])
print(Mat)
snipA = Mat.diagonal()
snipB = snipA[1:len(snipA)-1]
print(snipA)
print(snipB)
There are two problems now. First, I cannot modify snipB in any way. I get the error: "output array is read-only". Second, how can I save a modified snipB into the matrix again?
Any help is appreciated.
Upvotes: 2
Views: 81
Reputation: 14399
You can also do this with einsum
since numpy 1.10
np.einsum('ii->i', mat)[1:-1] = 0
mat
array([[11, 12, 13, 14, 15],
[21, 0, 23, 24, 25],
[31, 32, 0, 34, 35],
[41, 42, 43, 0, 45],
[51, 52, 53, 54, 55]])
Upvotes: 0
Reputation: 78554
You can index and modify a part of the diagonal like so:
>>> subdiag = np.arange(1, len(mat)-1)
>>> mat[subdiag, subdiag]
array([22, 33, 44])
>>> mat[subdiag, subdiag] = 0
>>> mat
array([[11, 12, 13, 14, 15],
[21, 0, 23, 24, 25],
[31, 32, 0, 34, 35],
[41, 42, 43, 0, 45],
[51, 52, 53, 54, 55]])
>>>
>>> mat[subdiag, subdiag] = [22, 33, 44]
>>> mat
array([[11, 12, 13, 14, 15],
[21, 22, 23, 24, 25],
[31, 32, 33, 34, 35],
[41, 42, 43, 44, 45],
[51, 52, 53, 54, 55]])
Upvotes: 3