2

I am trying to update multiple columns of a set of rows simultaneously. (in my case I have the same number of columns and the number of rows -- I'm making a similarity matrix, but generally speaking, this shouldn't be important). Is there a way to do this more efficiently than my examples below? -- I'm open to using python lists, pandas or numpy; doesn't really matter; as long as it's the fastest.

Example 1 - Two nested for loops

adj_mat = np.array([[1,1,1,0,0,0,0,0,0],
                [1,1,1,0,0,0,0,0,0],
                [1,1,1,1,0,0,0,0,0],
                [0,0,1,1,1,1,0,0,0],
                [0,0,0,1,1,1,0,0,0],
                [0,0,0,1,1,1,1,0,0],
                [0,0,0,0,0,1,1,1,1],
                [0,0,0,0,0,0,1,1,1],
                [0,0,0,0,0,0,1,1,1]])
inlier_mask = np.array([False, False, False, True, True, True, False, 
False, False])
inlier_idx = np.array(np.nonzero(inlier_mask))[0].tolist()

for i in inlier_idx:
    for j in inlier_idx:
        adj_mat[i,j] += 1

print(adj_mat)

Output:

[[1 1 1 0 0 0 0 0 0]
 [1 1 1 0 0 0 0 0 0]
 [1 1 1 1 0 0 0 0 0]
 [0 0 1 2 2 2 0 0 0]
 [0 0 0 2 2 2 0 0 0]
 [0 0 0 2 2 2 1 0 0]
 [0 0 0 0 0 1 1 1 1]
 [0 0 0 0 0 0 1 1 1]
 [0 0 0 0 0 0 1 1 1]]

Example 2 - Only one for loop

adj_mat = np.array([[1,1,1,0,0,0,0,0,0],
                [1,1,1,0,0,0,0,0,0],
                [1,1,1,1,0,0,0,0,0],
                [0,0,1,1,1,1,0,0,0],
                [0,0,0,1,1,1,0,0,0],
                [0,0,0,1,1,1,1,0,0],
                [0,0,0,0,0,1,1,1,1],
                [0,0,0,0,0,0,1,1,1],
                [0,0,0,0,0,0,1,1,1]])
inlier_mask = np.array([False, False, False, True, True, True, False, 
False, False])
inlier_idx = np.array(np.nonzero(inlier_mask))[0].tolist()

for i in inlier_idx:
    adj_mat[i,inlier_idx] += 1

Output:

[[1 1 1 0 0 0 0 0 0]
 [1 1 1 0 0 0 0 0 0]
 [1 1 1 1 0 0 0 0 0]
 [0 0 1 2 2 2 0 0 0]
 [0 0 0 2 2 2 0 0 0]
 [0 0 0 2 2 2 1 0 0]
 [0 0 0 0 0 1 1 1 1]
 [0 0 0 0 0 0 1 1 1]
 [0 0 0 0 0 0 1 1 1]]

Is there a solution such as: adj_mat[inlier_idx,inlier_idx] += 1 that can achieve this with no loops?

1 Answer 1

2

Use np.ix_ to create two broadcastable indexing arrays and then index and add -

adj_mat[np.ix_(inlier_idx, inlier_idx)] += 1
# or adj_mat[np.ix_(inlier_mask, inlier_mask)] += 1

Alternatively, we can manually create the broadcastable arrays with extending inlier_idx to 2D with None/np.newaxis -

inlier_idx = np.flatnonzero(inlier_mask)
adj_mat[inlier_idx[:,None], inlier_idx] += 1
Sign up to request clarification or add additional context in comments.

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.