Kevin Fang
Kevin Fang

Reputation: 2012

numpy mask using np.where then replace values

I've got two 2-D numpy arrays with same shape, let's say (10,6).

The first array x is full of some meaningful float numbers.

x = np.arange(60).reshape(-1,6)

The second array a is sparse array, with each row contains ONLY 2 non-zero values.

a = np.zeros((10,6))
for i in range(10):
    a[i, 1] = 1
    a[i, 2] = 1

Then there's a third array with the shape of (10,2), and I want to update the values of each row to the first array x at the position where a is not zero.

v = np.arange(20).reshape(10,2)

so the original x and the updated x will be:

array([[ 0,  1,  2,  3,  4,  5],
   [ 6,  7,  8,  9, 10, 11],
   [12, 13, 14, 15, 16, 17],
   [18, 19, 20, 21, 22, 23],
   [24, 25, 26, 27, 28, 29],
   [30, 31, 32, 33, 34, 35],
   [36, 37, 38, 39, 40, 41],
   [42, 43, 44, 45, 46, 47],
   [48, 49, 50, 51, 52, 53],
   [54, 55, 56, 57, 58, 59]])

and

array([[ 0,  0,  1,  3,  4,  5],
   [ 6,  2,  3,  9, 10, 11],
   [12,  4,  5, 15, 16, 17],
   [18,  6,  7, 21, 22, 23],
   [24,  8,  9, 27, 28, 29],
   [30, 10, 11, 33, 34, 35],
   [36, 12, 13, 39, 40, 41],
   [42, 14, 15, 45, 46, 47],
   [48, 16, 17, 51, 52, 53],
   [54, 18, 19, 57, 58, 59]])

I've tried the following method

x[np.where(a!=0)] = v

Then I got an error of shape mismatch: value array of shape (10,2) could not be broadcast to indexing result of shape (20,)

What's wrong with this approach, is there an alternative to do it? Thanks a lot.

Upvotes: 0

Views: 321

Answers (2)

hyloop
hyloop

Reputation: 359

import numpy as np

arrayOne = np.random.rand(6).reshape((2, 3))
arrayTwo = np.asarray([[0,1,2], [1,2,0]])
arrayThree = np.zeros((2, 2))

arrayOne[arrayTwo != 0] = arrayThree.ravel()
print(arrayOne)

[[0.56251284 0.         0.        ]
 [0.         0.         0.20076913]]

Note regarding edit: The solution above is not mine, all credit goes to Divakar. I edited because my earlier answer misunderstood OP's question and I wish to avoid confusion.

Upvotes: 0

Kevin Fang
Kevin Fang

Reputation: 2012

Thanks to the comment by @Divakar, the problem happens because the shapes of the two variables on both side of the assignment mark = are different.

To the left, the expression x[np.where(a!=0)] or x[a!=0] or x[np.nonzero(a)] are not structured, which has a shape of (20,)

To the right, we need an array of similar shape to finish the assignment. Therefore, a simple ravel() or reshape(-1) will do the job.

so the solution is as simple as x[a!=0] = v.ravel().

Upvotes: 1

Related Questions