There\'s a bunch of questions that are phrased similarly, but I was unable to find one that actually mapped to my intended semantics.
There are two lists, A
You can easily do this with numpy
by sorting both lists (to get a mapping between the two lists) and by inverting one of the sorting permutations:
import numpy as np
a = [7, 14, 0, 9, 19, 9]
b = [45, 42, 0, 1, -1, 0]
a = np.array(a)
b = np.array(b)
ai = np.argsort(a)
bi = np.argsort(b)
aiinv = np.empty(ai.shape,dtype=int)
aiinv[ai] = np.arange(a.size) # inverse of ai permutation
b_new = b[bi[aiinv]]
# array([ 0, 42, -1, 0, 45, 1])
numpy.argsort gives the indices (permutation) that will sort your array. This needs to be inverted to be used inside b
, which can be done by the inverted assignment
aiinv[ai] = np.arange(a.size)
a = [7, 14, 0, 9, 19, 9]
b = [45, 42, 0, 1, -1, 0]
print zip(*sorted(zip(sorted(b), sorted(enumerate(a), key=lambda x:x[1])), key=lambda x: x[1][0]))[0]
#or, for 3.x:
print(list(zip(*sorted(zip(sorted(b), sorted(enumerate(a), key=lambda x:x[1])), key=lambda x: x[1][0])))[0])
result:
(0, 42, -1, 0, 45, 1)
You sort a
, using enumerate
to keep track of each item's original index. You zip the result with sorted(b)
, then re-sort the whole thing based on a
's original indices. Then you call zip
once more to extract just b
's values.