2

I'm trying to dynamically construct a 2-D matrix with numpy based on the values of an array, like this:

In [113]: A = np.zeros((5,5),dtype=bool)
In [114]: A
Out[114]: array([[False, False, False, False, False],
   [False, False, False, False, False],
   [False, False, False, False, False],
   [False, False, False, False, False],
   [False, False, False, False, False]], dtype=bool)

 In [116]: B = np.array([0,1,3,0,2])

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

Now, I'd like to use the values of B to assign the first n values of each row to A to True. For this A and B, the correct output would be:

In [118]: A
Out[118]: array([[False, False, False, False, False],
   [ True, False, False, False, False],
   [ True,  True,  True, False, False],
   [False, False, False, False, False],
   [ True,  True, False, False, False]], dtype=bool)

The length of B will always equal the number of rows of A, and the the values of B will always be less than or equal to the number of columns of A. The size of A and the values of B are constantly changing, so I need to build these on the fly.

I'm certain that this has a simple(-ish) solution in numpy, but I've spent the last hour banging my head against variations of repeat, tile, and anything else I can think of. Can anyone help me out before I give myself a concussion? :)

EDIT: I'm going to need to do this a lot, so speed will be an issue. The only version that I can come up with for now is something like:

np.vstack([ [True]*x + [False]*(500-x) for x in B ])

but I expect that this will be slow due to the for loop (I would time it if I had anything to compare it to).

1 Answer 1

3

How about:

>>> A = np.zeros((5, 7),dtype=bool)
>>> B = np.array([0,1,3,0,2])
>>> (np.arange(len(A[0])) < B[:,None])
array([[False, False, False, False, False, False, False],
       [ True, False, False, False, False, False, False],
       [ True,  True,  True, False, False, False, False],
       [False, False, False, False, False, False, False],
       [ True,  True, False, False, False, False, False]], dtype=bool)

(I changed the shape from (5,5) because I was getting confused about which axis was which, and I wanted to make sure I was using the right one.)

[Simplified from (np.arange(len(A[0]))[:,None] < B).T -- if we expand B and not A, there's no need for the transpose.]

Sign up to request clarification or add additional context in comments.

1 Comment

Note that you don't need to actually build A-- I only did it to check the shape. All you need is the number len(A[0]) and B.

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.