我希望将一个数组的值的顺序与另一个数组的顺序相匹配。 例如,我有A和B:
A = [239 1678 2678 4430 199]
订单A:
A5< A1< A2< A3< A4
现在我的B列表是:
B = [ 4126.77552299 984.39685939 237.92397237 497.72447701 3377.17916825]
订单B:
B3< B4< B2< B5< B1
我希望B与A的顺序相同,如下所示:
B = [ 497.72447701 984.39685939 3377.17916825 4126.77552299 237.92397237]
订单B:
B5< B1< B2< B3< B4
A和B是示例,在我的例子中,我有很多具有许多不同大小的向量元组。我需要一个普遍的表达来命令一个向量在另一个向量的函数。
我该怎么办?
答案 0 :(得分:5)
我们按常规排序顺序对B进行排序:
sorted_B = sorted(B)
找出sorted_B
的每个元素应该去的地方:
locations = sorted(range(len(A)), key=A.__getitem__)
将这些元素放在他们需要的结果中:
result = [None]*len(B)
for i, elem in zip(locations, sorted_B):
result[i] = elem
这里有一个link演示文稿,显示这会为您的示例生成正确的输出。
如果您想直接将结果填回B
而不是副本,则可以这样做:
sorted_B = sorted(B)
locations = sorted(range(len(A)), key=A.__getitem__)
for i, elem in zip(locations, sorted_B):
B[i] = elem
如果您在NumPy中工作并且这些是NumPy数组而不是列表,我们应该使用NumPy操作来完成工作:
sorted_B = numpy.sort(B)
locations = numpy.argsort(A)
result = numpy.empty_like(B)
result[locations] = sorted_B
或更少的行:
result = numpy.empty_like(B)
result[numpy.argsort(A)] = numpy.sort(B)
或者,如果您想将结果填入B
而不是副本:
B[np.argsort(A)] = np.sort(B)
答案 1 :(得分:2)
您可以创建一个临时字典来映射已排序列表的索引与订单。然后使用临时字典获取所需的结果:
>>> A = [ 239, 1678, 2678, 4430, 199]
>>> B = [4126.77552299, 984.39685939, 237.92397237, 497.72447701, 3377.17916825]
# Temporary dict for mapping the `index` key with order as `value`
>>> order = {A.index(j): i for i, j in enumerate(sorted(A))}
>>> order
{0: 1, 1: 2, 2: 3, 3: 4, 4: 0}
>>> sorted_B = sorted(B) # sorted `B` list
>>> ordered_B = [sorted_B[order[i]] for i in range(len(B))]
>>> ordered_B # desired output
[497.72447701, 984.39685939, 3377.17916825, 4126.77552299, 237.92397237]
答案 2 :(得分:2)
这是另一种方法。使用带有sorted
参数的key
来使用您想要的任何键函数。
from operator import itemgetter
A = [239, 1678, 2678, 4430, 199]
B = [4126.77552299, 984.39685939, 237.92397237, 497.72447701, 3377.17916825]
# first get the order of list A
order, _ = zip(*sorted(enumerate(A), key=itemgetter(1)))
# then use that order to sort the other list
[n[0] for n in sorted(zip(sorted(B), order), key=itemgetter(1))]
[497.72447701, 984.39685939, 3377.17916825, 4126.77552299, 237.92397237]
您可以使用此lambda itemgetter(1)
key=lambda x: x[1]
编辑:正如@mkrieger所指出的,如果你对元组列表进行排序,如果你将键值作为元组中的第一个元素,则实际上并不需要键函数。
zip(A, range(len(A)))
类似于枚举,但索引和项目已交换。
所以这也会得到相同的结果,代码更简单,因为你不需要关键函数,也不需要导入。
order = [i for _, i in sorted(zip(A, range(len(A))))]
B = [b for _, b in sorted(zip(order, sorted(B)))]