Reputation: 27
I have an array of size 5 x 3 x 3.
I want to fill the diagonal of each 3 x 3 block with a number.
How can I do this efficiently using numpy (A python library).
My starting matrix is this:
[[[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 0 0]]
[[0 0 0]
[0 0 0]
[0 0 0]]
[[0 0 0]
[0 0 0]
[0 0 0]]]
and I want something like this:
[[[0.07735655 0 0 ]
[0 0.11476396 0 ]
[0 0 0.09903619]]
[[0.1923885 0 0 ]
[0 0.03063454 0 ]
[0 0 0.06028193]]
[[0.06566275 0 0 ]
[0 0.03151423 0 ]
[0 0 0.04042383]]
[[0.07950743 0 0 ]
[0 0.03250461 0 ]
[0 0 0.0448308 ]]
[[0.10879917 0 0 ]
[0 0.04700161 0 ]
[0 0 0.03924387]]]
Upvotes: 1
Views: 93
Reputation: 61455
How about using a for
loop along with numpy.fill_diagonal
?
In [33]: zeros = np.zeros((5, 3, 3))
# desired values to be filled along the diagonals;
# can also be 1D numpy arrays instead of Python lists
In [34]: diagonals = [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
In [35]: for idx, diag in enumerate(diagonals):
...: np.fill_diagonal(zeros[idx], diag)
...:
In [36]: zeros
Out[36]:
array([[[1., 0., 0.],
[0., 2., 0.],
[0., 0., 3.]],
[[1., 0., 0.],
[0., 2., 0.],
[0., 0., 3.]],
[[1., 0., 0.],
[0., 2., 0.],
[0., 0., 3.]],
[[1., 0., 0.],
[0., 2., 0.],
[0., 0., 3.]],
[[1., 0., 0.],
[0., 2., 0.],
[0., 0., 3.]]])
Upvotes: 1
Reputation: 3722
You can use this:
diag_ind_y, diag_ind_x = np.diag_indices(3)
arr1[:, diag_ind_y, diag_ind_x] = diag_vals
Testing it out:
import numpy as np
arr1 = np.zeros(shape=(5,3,3), dtype=np.float64) # Your array
diag_vals = np.random.rand(5,3) # The source of your diag values
diag_ind_y, diag_ind_x = np.diag_indices(3) # Returns arrays [0,1,2] and [0,1,2]
arr1[:, diag_ind_y, diag_ind_x] = diag_vals
print (arr1)
Output:
[[[0.69514006 0. 0. ]
[0. 0.4014048 0. ]
[0. 0. 0.473671 ]]
[[0.12769874 0. 0. ]
[0. 0.8565723 0. ]
[0. 0. 0.69453857]]
[[0.00943213 0. 0. ]
[0. 0.81497541 0. ]
[0. 0. 0.6915095 ]]
[[0.33894452 0. 0. ]
[0. 0.24649647 0. ]
[0. 0. 0.61987433]]
[[0.30184036 0. 0. ]
[0. 0.66978532 0. ]
[0. 0. 0.34574364]]]
Upvotes: 1