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.