简体   繁体   中英

Sort one list to to make two lists have correct order correspondence

I have two lists, eg

coords = [2, 0, 1, 4, 3]
value = [1, 9, 3, 3, 0]

where the first one is a series of coordinates, and the second one is a series of values corresponding to the coordinates, eg coordinate '2' corresponds to the value '1' , coords '0' gives value '9' .

Now, I would like to sort coords but keep the order of value unchanged, such that the smallest coords element corresponds to the smallest element in value , and so on. The desired output would be:

coords_new = [1, 4, 2, 3, 0]
value = [1, 9, 3, 3, 0] # unchanged

where '0' -> '0', '1' -> '1', '2' -> '3', '3' -> '3', '4' -> '9' . Any ideas to do that? You can return coords_new , or the indices that reorders the coords as answer.

Edit: If possible, I prefer we can return the indices that reorders the original coords , ie return the idx such that coords[idx] = coords_new .

Thanks a lot!

Zhihao

One alternative is to first create the mapping between the objects and then use this mapping combined with index:

coords = [2, 0, 1, 4, 3]
value = [1, 9, 3, 3, 0]

table = {k: v for k, v in zip(sorted(coords), sorted(value))}
print(table)
print(sorted(coords, key=lambda e: value.index(table[e])))

Output

{0: 0, 1: 1, 2: 3, 3: 3, 4: 9}
[1, 4, 2, 3, 0]

Note

This method assumes coords only contains unique values. For the general case you could generate the pairs (c, v) of the mapping an sort by the index value of v in value:

pairs = [(k, v) for k, v in zip(sorted(coords), sorted(value))]
result = [k for k, _ in sorted(pairs, key=lambda e: value.index(e[1]))]

print(result)

Output

[1, 4, 2, 3, 0]

Here are one and a half solutions using argsort. The kind='mergesort' kwd argument is only necessary if you require a stable sort. In your example, an unstable sort may also yield coords_new == [1, 4, 3, 2, 0] . If that is not a problem you can omit the kwd arg and allow numpy to use a faster sort algorithm.

import numpy as np

coords = [2, 0, 1, 4, 3]
value = [1, 9, 3, 3, 0]

coords, value = map(np.asanyarray, (coords, value))

vidx = value.argsort(kind='mergesort') # mergesort is stable, i.e. it  
                                       # preserves the order of equal elements

# direct method:
coords_new = np.empty_like(coords)
coords_new[vidx] = np.sort(coords)

# method yielding idx
idx = np.empty_like(vidx)
idx[vidx] = coords.argsort(kind='mergesort') 

The second method yields idx such that coords_new == coords[idx] .

I'm assuming you want a numpy answer since you've tagged numpy:

>>> x = np.argsort(value)
>>> x[x]
array([1, 4, 2, 3, 0])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM