2

Given a numpy array,

a = np.zeros((10,10))
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

And for a set of indices, e.g.:

start = [0,1,2,3,4,4,3,2,1,0]
end = [9,8,7,6,5,5,6,7,8,9]

how do you get the "select" all the values/range between the start and end index and get the following:

result = [[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
 [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
 [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
 [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 1]]

My goal is to 'select' the all the values between the each given indices of the columns.

I know that using apply_along_axis can do the trick, but is there a better or more elegant solution?

Any inputs are welcomed!!

asked Jul 15, 2017 at 13:26

1 Answer 1

10

You can use broadcasting -

r = np.arange(10)[:,None]
out = ((start <= r) & (r <= end)).astype(int)

This would create an array of shape (10,len(start). Thus, if you need to actually fill some already initialized array filled_arr, do -

m,n = out.shape
filled_arr[:m,:n] = out

Sample run -

In [325]: start = [0,1,2,3,4,4,3,2,1,0]
 ...: end = [9,8,7,6,5,5,6,7,8,9]
 ...: 
In [326]: r = np.arange(10)[:,None]
In [327]: ((start <= r) & (r <= end)).astype(int)
Out[327]: 
array([[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
 [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
 [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
 [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 1]])

If you meant to use this as a mask with 1s as the True ones, skip the conversion to int. Thus, (start <= r) & (r <= end) would be the mask.

answered Jul 15, 2017 at 13:30

7 Comments

Given an arbitrary ndarray of shape (10,10) how would you use this to select the desired items/elements?
@wwii Well the output ncols = len(start) and output nrows user has to specify. But for a "squeezed in" version, it would be end.max()+1. I have kept it as np.arange(10)[:,None] with 10 being the no. of rows. But yes, in a generic sense, we would need to initialize and assign with those number of rows and cols as the slice ends along each axis.
@wwii On that term, "select", I think OP meant "select and assign". But again, OP could have meant to use the 1s as a selection mask to select from some other array. That's a possible way to interpret as well.
@Divakar Yup, i intended to use it as a mask
@snowflake Do (a*mask).sum(0) or np.einsum('ij,ij->j',a,mask).
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.