1

The objective is randomly assign a constant value to tril of a numpy array. I wonder whether there is more efficient and compact than the proposed solution below.

import numpy as np
import random

rand_n2 = np.random.randn(10,10)
arr=np.tril(rand_n2,-1)
n=np.where(arr!=0)
nsize=n[0].shape[0]
rand_idx = random.sample(range(1,nsize), nsize-1)
ndrop=2 # Total location to assign the contant value
for idx in range(ndrop):
    arr[n[0][rand_idx[idx]],n[1][rand_idx[idx]]]=10 # Assign constant value to random tril location
1
  • Is the input matrix always square? Commented Sep 8, 2021 at 18:59

2 Answers 2

1

You could initialize a matrix with random numbers, and overwrite the upper triangle the you take random indexes from the lower triangle indexes and overwrite them:

import numpy as np

# create the matrix with random values
size = 5
arr = np.random.rand(size, size)
arr[np.triu_indices(size, k=0)] = 0

# set values randomly
val = 10
k_max = 2
ix = np.random.choice(range(int((size*size-size)/2)), k_max)
rnd = np.tril_indices(size, k=-1)
arr[(rnd[0][ix], rnd[1][ix])] = val

array([[ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.50754565,  0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.98920062,  0.53945212,  0.        ,  0.        ,  0.        ],
       [ 0.54987252, 10.        ,  0.22052519,  0.        ,  0.        ],
       [10.        ,  0.82057924,  0.86199411,  0.85397047,  0.        ]])
Sign up to request clarification or add additional context in comments.

Comments

1

Don't know if this is much more efficient and compact, but I feel it's a bit cleaner and easier to read:

import numpy as np

rand_n2 = np.random.randn(10,10)
arr=np.tril(rand_n2,-1)

# create list of lower trianguler indices
tril_idx = [(i,j) for i in range(1,10) for j in range(i)]
# shuffle indices i.e. draw two at random
np.random.shuffle(tril_idx)

ndrop = 2 # Total location to assign the contant value
for idx in tril_idx[:ndrop]:
    arr[idx] = 10 # Assign constant value to random tril location

Instead of using the double list comprehension to create the list of lower triangular indices, you can use np.tril_indices() as well. Just take care since this will return a tuple of arrays of rather than a array of tuples.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.