lanery
lanery

Reputation: 5364

Sort numpy string array using positional data

I have a numpy array of strings

names = array([
    'p00x00', 'p01x00', 'p02x00', 'p03x00', 'p04x00', 'p05x00',
    'p00x01', 'p01x01', 'p02x01', 'p03x01', 'p04x01', 'p05x01',
    'p00x02', 'p01x02', 'p02x02', 'p03x02', 'p04x02', 'p05x02',
    'p00x03', 'p01x03', 'p02x03', 'p03x03', 'p04x03', 'p05x03',
    'p00x04', 'p01x04', 'p02x04', 'p03x04', 'p04x04', 'p05x04',
    'p00x05', 'p01x05', 'p02x05', 'p03x05', 'p04x05', 'p05x05'])

And corresponding position data

X = array([2.102235, 2.094113, 2.086038, 2.077963, 2.069849, 2.061699])
Y = array([-7.788431, -7.780364, -7.772306, -7.764247, -7.756188, -7.748114])

How can I sort names using X and Y such that I get out a sorted grid of names with shape (6, 6)? Note that there are essentially 6 unique X and Y positions -- I'm not just arbitrarily choosing 6x6.

names = array([
    ['p00x00', 'p01x00', 'p02x00', 'p03x00', 'p04x00', 'p05x00'],
    ['p00x01', 'p01x01', 'p02x01', 'p03x01', 'p04x01', 'p05x01'],
    ['p00x02', 'p01x02', 'p02x02', 'p03x02', 'p04x02', 'p05x02'],
    ['p00x03', 'p01x03', 'p02x03', 'p03x03', 'p04x03', 'p05x03'],
    ['p00x04', 'p01x04', 'p02x04', 'p03x04', 'p04x04', 'p05x04'],
    ['p00x05', 'p01x05', 'p02x05', 'p03x05', 'p04x05', 'p05x05']])

I realize in this case that I could simply reshape the array, but in general the data will not work out this neatly.

Upvotes: 0

Views: 55

Answers (1)

Thomas Kühn
Thomas Kühn

Reputation: 9820

You can use numpy.argsort to get the indexes of the elements of an array after it's sorted. These indices you can then use to sort your names array.

import numpy as np

names = np.array([
    'p00x00', 'p01x00', 'p02x00', 'p03x00', 'p04x00', 'p05x00',
    'p00x01', 'p01x01', 'p02x01', 'p03x01', 'p04x01', 'p05x01',
    'p00x02', 'p01x02', 'p02x02', 'p03x02', 'p04x02', 'p05x02',
    'p00x03', 'p01x03', 'p02x03', 'p03x03', 'p04x03', 'p05x03',
    'p00x04', 'p01x04', 'p02x04', 'p03x04', 'p04x04', 'p05x04',
    'p00x05', 'p01x05', 'p02x05', 'p03x05', 'p04x05', 'p05x05'])

X = np.array([2.102235, 2.094113, 2.086038, 2.077963, 2.069849, 2.061699])
Y = np.array([-7.788431, -7.780364, -7.772306, -7.764247, -7.756188, -7.748114])

x_order = np.argsort(X)
y_order = np.argsort(Y)

names_ordered = names.reshape(6,6)[np.meshgrid(x_order,y_order)]

print(names_ordered)

gives the following output:

[['p00x05' 'p00x04' 'p00x03' 'p00x02' 'p00x01' 'p00x00']
 ['p01x05' 'p01x04' 'p01x03' 'p01x02' 'p01x01' 'p01x00']
 ['p02x05' 'p02x04' 'p02x03' 'p02x02' 'p02x01' 'p02x00']
 ['p03x05' 'p03x04' 'p03x03' 'p03x02' 'p03x01' 'p03x00']
 ['p04x05' 'p04x04' 'p04x03' 'p04x02' 'p04x01' 'p04x00']
 ['p05x05' 'p05x04' 'p05x03' 'p05x02' 'p05x01' 'p05x00']]

Upvotes: 2

Related Questions