1

If I have an index array with all unique sequential values, such as:

index_array = array([0, 4, 2, 5, 6, 1, 3, 7, 8])

with a corresponding value array:

value_array = array([0, 400, 200, 500 600, 100, 300, 700, 800])

is it possible to loop through the index array in sequential order, such that I get

array([0, 100, 200, 300, 400, 500, 600, 700, 800])

I need to loop through the index array in order (i.e. 0, 1, 2, 3, 4...) with the corresponding values (i.e. 0, 100, 200, 300, 400). The reason these values aren't in order is because I'm subdividing edges, which means the new edges are added at the end of the index array (using vstack), rather than inserted into the index array at the appropriate point.

The pseudocode (if I was printing out the values), would be something like this:

for point in sorted(index_array):

    print sorted(point(value_array))

producing:

0

100

200

300

How memory sensitive is this (I'm guessing I would need to use numpy.where) Is it just better practice to reorder before looping, or is there a performance cost to looping out of order?

6
  • 2
    value_array[index_array]? Commented Nov 10, 2017 at 10:46
  • As they're written they're lists and not numpy arrays. Commented Nov 10, 2017 at 10:48
  • @cᴏʟᴅsᴘᴇᴇᴅ From what I understand, OP wants to loop through the sorted index array, access the value array's matching values and print them. Commented Nov 10, 2017 at 10:50
  • @GPhilo is correct. I need to loop through a sorted index array and get the value arrays's matching values in order Commented Nov 10, 2017 at 10:51
  • @user2770149 Can you please clarify? As of now, it's a bit hard to understand what you want. I will reopen your question because it doesn't appear to be a dupe, but I still can't understand how you get your expected output. Commented Nov 10, 2017 at 10:52

1 Answer 1

5

Approach #1

Get the argsort for index array and index into values array -

value_array[index_array.argsort()]

Sample run -

In [129]: value_array
Out[129]: array([   0,  400,  200,  500,  600,  100,  300,  700, 800])

In [130]: index_array
Out[130]: array([0, 4, 2, 5, 6, 1, 3, 7, 8])

In [131]: value_array[index_array.argsort()]
Out[131]: array([   0,  100,  200,  300,  400,  500,  600,  700, 800])

Approach #2 Abusing the fact that all elements in index_array are unique and sequential, a much faster way would be to initialize an output array and use those indices to index and assign those values from value_array into it, like so -

def assign_unique_seq(value_array, index_array):
    out = np.empty_like(value_array)
    out[index_array] = value_array
    return out

Runtime test -

In [152]: value_array = np.random.randint(0,1000000,(100000))

# Create unique and sequential indices array
In [153]: index_array = np.random.permutation(len(value_array))

In [154]: %timeit value_array[index_array.argsort()]
100 loops, best of 3: 7.84 ms per loop

In [155]: %timeit assign_unique_seq(value_array, index_array)
1000 loops, best of 3: 240 µs per loop
Sign up to request clarification or add additional context in comments.

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.