0
mask = np.tril(np.ones(3, dtype=bool)
print mask
[[ True False False]
 [ True True False]
 [ True True True]]

B = np.zeros(9)
B.shape = (3,3)
print B
[[ 0 0 0 ]
 [ 0 0 0 ]
 [ 0 0 0 ]]

B[mask] 
array([0,0,0,0,0,0])

C = np.array([[1],[0],[0],[1],[0],[1]])

B[mask] = C
ValueError: boolean index array should have 1 dimension

I tried to apply .flatten():

B[mask] = C.flatten()
print B
array([[1, 0, 0],
      [0, 0, 0],
      [1, 0, 1]])

But my intended result is a diagonal matrix.

array([[1, 0, 0],
      [0, 1, 0],
      [0, 0, 1]])

What am I doing wrong?

4
  • 1
    What am I doing wrong? - Assuming it's column major order. To solve it : B.T[mask.T] = C.flatten() I believe. Commented Apr 13, 2018 at 10:36
  • DennisJung if @Divakar answer is the correct one you should ask him to post his comment as answer and mark it as correct. Commented Apr 13, 2018 at 10:42
  • @CataJohn Thank you Mr.John. this is my first question@stackoverflow. I'm newbie here. Thanks. Commented Apr 13, 2018 at 10:44
  • @Divakar Your answer is what i exactly want! Please post your comment as answer. Commented Apr 13, 2018 at 10:47

2 Answers 2

1

You want np.diag_indices function that gives you the indices to access the main diagonal of an array, not tril:

In [10]: a = np.zeros((3, 3))

In [11]: indices = np.diag_indices(3)

In [12]: a[indices] = 1

In [13]: a
Out[13]: 
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
Sign up to request clarification or add additional context in comments.

Comments

0

The issue is you are assuming column-major ordered values, which is not the case with NumPy/Python. So, for a general case of using a mask to assign values with the column-major ordered values, we need to transpose both the input array and mask and assign those, like so -

B.T[mask.T] = C.flatten()

Sample run for explanation on getting the right order and assigning -

In [36]: B = np.arange(1,10).reshape(3,3)

In [37]: B
Out[37]: 
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

In [38]: mask = np.tril(np.ones(3, dtype=bool))

In [39]: mask
Out[39]: 
array([[ True, False, False],
       [ True,  True, False],
       [ True,  True,  True]])

In [40]: B.T[mask.T] 
Out[40]: array([1, 4, 7, 5, 8, 9]) # right order (col major) obtained

# Finally assign into masked positions
In [41]: B.T[mask.T] = C.flatten()

In [42]: B
Out[42]: 
array([[1, 2, 3],
       [0, 1, 6],
       [0, 0, 1]])

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.