3

I have a very simple question ,How to get numpy array from multiple lists of same length and sort along an axis ?

I'm looking for something like:

a = [1,1,2,3,4,5,6]
b = [10,10,11,09,22,20,20]
c = [100,100,111,090,220,200,200]
d = np.asarray(a,b,c)
print d
>>>[[1,10,100],[1,10,100],[2,11,111].........[6,20,200]]

2nd Question : And if this could be achieved can i sort it along an axis (for eg. on the values of List b)?

3rd Question : Can the sorting be done over a range ? for eg. for values between b+10 and b-10 while looking at List c for further sorting. like

[[1,11,111][1,10,122][1,09,126][1,11,154][1,11,191]
 [1,20,110][1,25,122][1,21,154][1,21,155][1,21,184]]
5
  • Have a look at this for your second question: stackoverflow.com/questions/2828059/… Commented May 31, 2015 at 19:19
  • You can use d = np.array([a,b, c]). Commented May 31, 2015 at 19:43
  • @tillstenm how is that the same as the requested output? Commented May 31, 2015 at 19:48
  • Can you explain more about your 3rd question? Commented May 31, 2015 at 20:54
  • its an ocr script , a = digit recognized , b = x coordinate , c = y coordinate ; as the objects(words/characters) in a line are taken in the script with a minor change in the "y" axis so the numbers in "c" are like "128,127,128,129,128,127,128,128" : Commented Jun 1, 2015 at 5:29

2 Answers 2

2

You can zip to get the array:

a = [1, 1, 2, 3, 4, 5, 6]
b = [10, 10, 11, 9, 22, 20, 20]
c = [100, 100, 111, 90, 220, 200, 200]
d = np.asarray(zip(a,b,c))
print(d)
[[  1  10 100]
 [  1  10 100]
 [  2  11 111]
 [  3   9  90]
 [  4  22 220]
 [  5  20 200]
 [  6  20 200]]

print(d[np.argsort(d[:, 1])]) # a sorted copy
[[  3   9  90]
[  1  10 100]
[  1  10 100]
[  2  11 111]
[  5  20 200]
[  6  20 200]
[  4  22 220]]

I don't know how you would do an inplace sort without doing something like:

d = np.asarray(zip(a,b,c))

d.dtype = [("0", int), ("1", int), ("2", int)]
d.shape = d.size
d.sort(order="1")

The leading 0 would make the 090 octal in python2 or invalid syntax in python3 so I removed it.

You can also sort the zipped elements before you pass the:

from operator import itemgetter
zipped = sorted(zip(a,b,c),key=itemgetter(1))


d = np.asarray(zipped)
print(d)
[[  3   9  90]
 [  1  10 100]
 [  1  10 100]
 [  2  11 111]
 [  5  20 200]
 [  6  20 200]
 [  4  22 220]]
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Padraic for your help, are u sure sorting can't be done over a range as I asked in the 3rd question ?
@ManipalKing, It most probably is, I am just trying to get my head around the logic! If you want an inplace sort as far as my np knowledge you would need a record type
@ManipalKing,where do 191, 184,155 etc.. come from?
its an ocr script , a = digit recognized , b = x coordinate , c = y coordinate ; as the objects(words/characters) in a line are taken in the script with a minor change in the "y" axis so the numbers in "c" are like "128,127,128,129,128,127,128,128"
1

You can use np.dstack and np.lexsort . for example if you want to sort based on the array b(second axis) then a and then c :

>>> d=np.dstack((a,b,c))[0]
>>> indices=np.lexsort((d[:,1],d[:,0],d[:,2]))
>>> d[indices]
array([[  3,   9,  90],
       [  1,  10, 100],
       [  1,  10, 100],
       [  2,  11, 111],
       [  5,  20, 200],
       [  6,  20, 200],
       [  4,  22, 220]])

1 Comment

@PadraicCunningham Why? its the expected sorted result based on second axis.

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.