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

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.