2

What is the most efficient way to sort two numpy matrices in parallel, row by row? A toy example:

sort this alpha:

a = [['c', 'b', 'e', 'd'], 
     ['a', 'd', 'b', 'e']]

then, sort this in parallel to a:

b = [['1', '2', '3', '4'], 
     ['2', '1', '4', '3']]

Result after sorting:

a = [['b', 'c', 'd', 'e'], 
     ['a', 'b', 'd', 'e']]

b = [['2', '1', '4', '3'], 
     ['2', '4', '1', '3']]

In my real case, a and b are large, 2D matrices of the same size.

If I use idx = a.argsort(), I obtain the indices to sort each row of a. Can these be applied to b in one step? b = b[idx] is not working.

user
  • 5,370
  • 8
  • 47
  • 75
Chris Parry
  • 2,937
  • 7
  • 30
  • 71
  • also your example is about 1d list and then you refer to 2d matrices, please give examples that match what you are doing. – Julien Nov 11 '16 at 09:20
  • b[idx] does not return an error, but the contents are not sorted. I will update the question toy example. – Chris Parry Nov 11 '16 at 09:23
  • Maybe this answer (how to apply argsort to 2D array) : http://stackoverflow.com/a/33141247/3981745 - eh, late. Browser hadn't refreshed. – ǝɲǝɲbρɯͽ Nov 11 '16 at 10:38

2 Answers2

3

You can use advanced indexing -

idxx = np.arange(a.shape[0])[:,None],a.argsort(1)
a_out = a[idxx]
b_out = b[idxx]

Sample run -

In [75]: a
Out[75]: 
array([['b', 'c', 'd', 'e'],
       ['a', 'b', 'd', 'e']], 
      dtype='|S1')

In [76]: b
Out[76]: 
array([['2', '1', '4', '3'],
       ['2', '4', '1', '3']], 
      dtype='|S1')

In [77]: a_out
Out[77]: 
array([['b', 'c', 'd', 'e'],
       ['a', 'b', 'd', 'e']], 
      dtype='|S1')

In [78]: b_out
Out[78]: 
array([['2', '1', '4', '3'],
       ['2', '4', '1', '3']], 
      dtype='|S1')
Divakar
  • 218,885
  • 19
  • 262
  • 358
0

Try this one

Python 3.4.3 (default, Sep 14 2016, 12:36:27) 
    [GCC 4.8.4] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> a = ['c', 'b', 'e', 'd']
    >>> b = [1,    2,   3,   4 ]
    >>> a,b=zip(*sorted(zip(a, b)))
    >>> a
    ('b', 'c', 'd', 'e')
    >>> b
    (2, 1, 4, 3)
    >>> 
Rohan Khude
  • 4,455
  • 5
  • 49
  • 47
  • This works for my toy example, but in the real one I get the error: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() – Chris Parry Nov 11 '16 at 09:18