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]]
Manipal King
  • 422
  • 1
  • 5
  • 18

2 Answers2

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]]
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • Thanks Padraic for your help, are u sure sorting can't be done over a range as I asked in the 3rd question ? – Manipal King May 31 '15 at 19:38
  • @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 – Padraic Cunningham May 31 '15 at 19:41
  • @ManipalKing,where do `191, 184,155` etc.. come from? – Padraic Cunningham May 31 '15 at 20:11
  • 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" – Manipal King Jun 01 '15 at 05:26
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]])
Mazdak
  • 105,000
  • 18
  • 159
  • 188