1

I have a list of numpy array indices which I created with argsort():

i = 
[array([0, 1, 3, 2, 4], dtype=int64),
 array([1, 3, 0, 2, 4], dtype=int64),
 array([2, 4, 0, 1, 3], dtype=int64),
 array([3, 1, 0, 2, 4], dtype=int64),
 array([4, 2, 0, 3, 1], dtype=int64)]

This is the corresponding list of arrays with values:

v =
[array([0.        , 0.19648367, 0.24237755, 0.200832  , 0.28600039]),
 array([0.19648367, 0.        , 0.25492185, 0.15594099, 0.31378135]),
 array([0.24237755, 0.25492185, 0.        , 0.25685254, 0.2042604 ]),
 array([0.200832  , 0.15594099, 0.25685254, 0.        , 0.29995309]),
 array([0.28600039, 0.31378135, 0.2042604 , 0.29995309, 0.        ])] 

When I try to loop over the lists like this:

for line in i:
    v[line]

I get the error:

TypeError: only integer scalar arrays can be converted to a scalar index

But when I try to access them individually like this:

v[0][i[0]]

It works and outputs the values in v[0] in correct order like this:

array([0.        , 0.19648367, 0.200832  , 0.24237755, 0.28600039])

I want the arrays in v ordered from the smallest value to biggest. What am I doing wrong?

6
  • What is s — that probably makes a difference here? Commented Apr 11, 2020 at 2:50
  • What result did you expect from that loop? But when I try to access them individually like this: Of course, that's a different operation. As an aside, is there any particular reason for using lists of ndarrays? Commented Apr 11, 2020 at 2:50
  • @MarkMeyer my bad thats supposed to be i Commented Apr 11, 2020 at 2:52
  • you forgot [0] in v[0][line] to have code similar to v[0][i[0]] Commented Apr 11, 2020 at 2:54
  • @AMC I want the arrays in v ordered from the smallest value to biggest. Commented Apr 11, 2020 at 2:55

2 Answers 2

2

This is all easier (and faster) if you don't use a python list of Numpy arrays, but instead use a multi-dimensional numpy array. Then you have all the great tool from numpy at you disposal and can avoid slow loops. For example for you can use np.take_along_axis:

from numpy import array 

i = np.array([
    [0, 1, 3, 2, 4],
    [1, 3, 0, 2, 4],
    [2, 4, 0, 1, 3],
    [3, 1, 0, 2, 4],
    [4, 2, 0, 3, 1]])


v = array([
    [0., 0.19648367, 0.24237755, 0.200832  , 0.28600039],
    [0.19648367, 0.        , 0.25492185, 0.15594099, 0.31378135],
    [0.24237755, 0.25492185, 0.        , 0.25685254, 0.2042604 ],
    [0.200832  , 0.15594099, 0.25685254, 0.        , 0.29995309],
    [0.28600039, 0.31378135, 0.2042604 , 0.29995309, 0.        ]] 
)


np.take_along_axis(v,i, 1)

result:

array([[0.        , 0.19648367, 0.200832  , 0.24237755, 0.28600039],
       [0.        , 0.15594099, 0.19648367, 0.25492185, 0.31378135],
       [0.        , 0.2042604 , 0.24237755, 0.25492185, 0.25685254],
       [0.        , 0.15594099, 0.200832  , 0.25685254, 0.29995309],
       [0.        , 0.2042604 , 0.28600039, 0.29995309, 0.31378135]])
Sign up to request clarification or add additional context in comments.

2 Comments

I agree that this way is best, assuming you don't need your array i with the indices in order - numpy has lots of built-in functions.
Thanks for the answer Mark. I will check my code to avoid lists of ndarrays.
1

Loop through each line of i, and loop through each line of v at the same time using enumerate:

import numpy as np 

i = np.array([[0, 1, 3, 2, 4], [1, 3, 0, 2, 4], [2, 4, 0, 1, 3], [3, 1, 0, 2, 4], [4, 2, 0, 3, 1]])

v = np.array([[0.        , 0.19648367, 0.24237755, 0.200832  , 0.28600039], 
[0.19648367, 0.        , 0.25492185, 0.15594099, 0.31378135],
[0.24237755, 0.25492185, 0.        , 0.25685254, 0.2042604 ],
[0.200832  , 0.15594099, 0.25685254, 0.        , 0.29995309],
[0.28600039, 0.31378135, 0.2042604 , 0.29995309, 0.        ]] )

# you can rearrange each line of v by using indices in each row of i
for index, line in enumerate(i):
    print(v[index][line])

Output:

[0.         0.19648367 0.200832   0.24237755 0.28600039]
[0.         0.15594099 0.19648367 0.25492185 0.31378135]
[0.         0.2042604  0.24237755 0.25492185 0.25685254]
[0.         0.15594099 0.200832   0.25685254 0.29995309]
[0.         0.2042604  0.28600039 0.29995309 0.31378135]

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.