5

I have an array of start and stop indices, like this:

    [[0, 3], [4, 7], [15, 18]]

and i would like to construct a 2D numpy array where each row is a range from the corresponding pair of start and stop indices, as follows:

    [[0, 1, 2],
    [4, 5, 6],
    [15, 16, 18]]

Currently, i am creating an empty array and filling it in a for loop:

    ranges = numpy.empty((3, 3))
    a = [[0, 3], [4, 7], [15, 18]]

    for i, r in enumerate(a):
        ranges[i] = numpy.arange(r[0], r[1])

Is there a more compact and (more importantly) faster way of doing this? possibly something that doesn't involve using a loop?

3
  • 1
    Just do np.asarray(a)[:, :1] + np.arange(a[0][1] - a[0][0]) Commented May 16, 2019 at 16:32
  • Would the difference between start and stop across all pairs be the same? Commented May 16, 2019 at 16:34
  • @Divakar, yes, they would be the same Commented May 17, 2019 at 8:10

2 Answers 2

4

One way is to use broadcast to add the left hand edges to the base arange:

In [11]: np.arange(3) + np.array([0, 4, 15])[:, None]
Out[11]:
array([[ 0,  1,  2],
       [ 4,  5,  6],
       [15, 16, 17]])

Note: this requires all ranges to be the same length.

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

1 Comment

Awesome! thanks. @jdehesa's solution also works but this seems to run a bit faster
2

If the ranges were to result in different lengths, for a vectorized approach you could use n_ranges from the linked solution:

a = np.array([[0, 3], [4, 7], [15, 18]])

n_ranges(a[:,0], a[:,1], return_flat=False)
# [array([0, 1, 2]), array([4, 5, 6]), array([15, 16, 17])]

Which would also work with the following array:

a = np.array([[0, 3], [4, 9], [15, 18]])
n_ranges(*a.T, return_flat=False)
# [array([0, 1, 2]), array([4, 5, 6, 7, 8]), array([15, 16, 17])]

2 Comments

Thanks for the complete solution, but i forgot to make it clear in my question that the ranges would all be the same length.
@yatu I don't see the return_flat-variable in the linked code?

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.