Reputation: 95
Suppose I have a 3D array, how can I fill the diag of the first two dimensions to zero. For example
a = np.random.rand(2,2,3)
for i in range(3):
np.fill_diagonal(a[:,:,i], 0)
Is there a way to replace the for loop?
Upvotes: 1
Views: 872
Reputation: 231335
In [6]: a = np.random.randint(1,10,(2,2,3))
...: for i in range(3):
...: np.fill_diagonal(a[:,:,i], 0)
In [7]: a
Out[7]:
array([[[0, 0, 0],
[7, 4, 4]],
[[8, 2, 7],
[0, 0, 0]]])
Indexing a diagonal is easy - just use the same index array for both dimensions. Thus the 0s we just set are:
In [8]: idx=np.arange(2)
In [9]: a[idx,idx,:]
Out[9]:
array([[0, 0, 0],
[0, 0, 0]])
and used to set a value:
In [10]: a[idx,idx,:] = 10
In [11]: a
Out[11]:
array([[[10, 10, 10],
[ 7, 4, 4]],
[[ 8, 2, 7],
[10, 10, 10]]])
Upvotes: 0
Reputation: 95
The following is one of the solution
a = np.random.rand(2,2,3)
np.einsum('iij->ij',a)[...] = 0
Upvotes: 2
Reputation: 54645
The np.diag function returns a 2D diagonal matrix.
a[:,:,0] = np.diag((1,1))
Upvotes: 0