Khaled Khafagy Khaled Khafagy - 3 months ago 17
Python Question

Numpy---How to substitute by certain multi-elements in array at the same time?

I have a problem during substitution with data in array:
say,

a = [1, 0, 0]
b = [0, 0, 0]
c = [0, 0]
X = numpy.zeros((3, 3, 2))


and I have Matrix
Y
with shape (2,3,2) and it is non a zero matrix

Now; I want to equal these elements of X by Y directly;

X[tuple(numpy.where(a==0)[0]),
tuple(numpy.where(b==0)[0]),
tuple(numpy.where(c==0)[0])] = Y


I got the error
shape mismatch: objects cannot be broadcast to a single shape

Answer

You could use np.ix_ to construct index arrays appropriate for indexing X:

import numpy as np
np.random.seed(2016)
a=np.array([1, 0, 0])
b=np.array([0, 0, 0])
c=np.array([0, 0])
X = np.zeros((3,3,2))
Y = np.random.randint(1, 10, size=(2,3,2))

idx = np.ix_(a==0, b==0, c==0)
X[idx] = Y
print(X)

yields

array([[[ 0.,  0.],
        [ 0.,  0.],
        [ 0.,  0.]],

       [[ 9.,  8.],
        [ 3.,  7.],
        [ 4.,  5.]],

       [[ 2.,  2.],
        [ 3.,  3.],
        [ 9.,  9.]]])

Alternatively, you could construct a boolean mask

mask = (a==0)[:,None,None] & (b==0)[None,:,None] & (c==0)[None,None,:]
X[mask] = Y

Indexing (a=0) as in (a==0)[:,None,None] adds new axes to the 1D boolean array (a=0). (a==0)[:,None,None] has shape (3,1,1). Similarly, (b==0)[None,:,None] has shape (1,3,1), and (c==0)[None,None,:] has shape (1,1,2).

When combined with & (bitwise-and), the three arrays are broadcasted to one common shape, (3,3,2). Thus, X gets indexed by one boolean array of shape (3,3,2) in

X[mask] = Y
Comments