如何将一个数组的顺序复制到另一个数组中? [蟒蛇]

时间:2017-02-05 17:46:05

标签: python

我希望将一个数组的值的顺序与另一个数组的顺序相匹配。 例如,我有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是示例,在我的例子中,我有很多具有许多不同大小的向量元组。我需要一个普遍的表达来命令一个向量在另一个向量的函数。

我该怎么办?

3 个答案:

答案 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)

Demo

或者,如果您想将结果填入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)))]

演示:http://ideone.com/zCXOHu