Python 如何有效地对向量进行排序,使其与另一个向量的距离最小?

Python 如何有效地对向量进行排序,使其与另一个向量的距离最小?,python,numpy,Python,Numpy,我有两个向量(v1,v2)。向量v2中的值需要进行排序,以便每个值都可以用v1中的元素进行标识。v1和v2中的值略有不同,但可能会切换。最后,我需要多次执行此操作,因为我需要根据已排序的v2对下一个v3进行排序,以此类推 我想看看v2中每种可能的值顺序的v2的不同排列。v1的最小差值之和应该是我想要的排序。这在原则上是可行的,但当v1和v2变大时,规模会变得非常糟糕 此代码显示一对v1、v2的顺序 import numpy as np import itertools def sort(v1,

我有两个向量(v1,v2)。向量v2中的值需要进行排序,以便每个值都可以用v1中的元素进行标识。v1和v2中的值略有不同,但可能会切换。最后,我需要多次执行此操作,因为我需要根据已排序的v2对下一个v3进行排序,以此类推

我想看看v2中每种可能的值顺序的v2的不同排列。v1的最小差值之和应该是我想要的排序。这在原则上是可行的,但当v1和v2变大时,规模会变得非常糟糕

此代码显示一对v1、v2的顺序

import numpy as np
import itertools

def sort(v1,v2):

    arr_permutations = np.array(list(itertools.permutations(v2)))

    sum_diff = np.sum(np.abs(arr_permutations - v1), axis=1)

    best_permut = arr_permutations[np.argmin(sum_diff)]

    return best_permut 

v1 = np.array([-0.99418 -0.106364j, -1.005974-0.099054j,
 -0.991923-0.107482j, -0.990868-0.107976j, -0.990558-0.108118j,
 -0.898555+0.035351j])

v2 = np.array([-1.0052  -0.10133j,  -0.993598-0.108516j,
  0.991379-0.109617j, -0.990341-0.110104j, -0.990036-0.110244j, 
 -0.898624+0.032346j])

sort(v1,v2)

Out:  np.array([-0.993598-0.108516j, -1.0052  -0.10133j, 
                -0.990341-0.110104j, -0.990036-0.110244j, 
                 0.991379-0.109617j, -0.898624+0.032346j])
在这种情况下,正确的顺序是在这种特定情况下交换v2[0]和v2[1]。由于属于彼此的值都会有一点变化,仅查看一个值并在v1中找到最接近该值的单个位置是不够的

编辑:我更改了示例并添加了函数的输出

编辑2:在numpy数组中添加了缺少的逗号

import numpy as np
from scipy import optimize

def match(v1, v2, dist):
    assert v1.ndim == v2.ndim == 1
    assert v1.shape[0] == v2.shape[0]
    n = v1.shape[0]
    t = np.dtype(dist(v1[0], v2[0]))
    dist_matrix = np.fromiter((dist(x1, x2) for x1 in v1 for x2 in v2),
                              dtype=t, count=n*n).reshape(n, n)
    row_ind, col_ind = optimize.linear_sum_assignment(dist_matrix)
    return v2[col_ind]

v1 = np.array([-0.99418 -0.106364j, -1.005974-0.099054j, -0.991923-0.107482j,
               -0.990868-0.107976j, -0.990558-0.108118j, -0.898555+0.035351j])
v2 = np.array([-1.0052  -0.10133j,  -0.993598-0.108516j,  0.991379-0.109617j,
               -0.990341-0.110104j, -0.990036-0.110244j, -0.898624+0.032346j])

v2_matched = match(v1, v2, lambda x1, x2: abs(x1 - x2))
print(repr(v2_matched))
# =>
# array([-0.993598-0.108516j, -1.0052  -0.10133j , -0.990341-0.110104j,
#        -0.990036-0.110244j,  0.991379-0.109617j, -0.898624+0.032346j])
输出与
sort()
的输出相同

如您所见,您可以插入不同的lambda或函数来计算距离

我不是numpy的专家,可能有一种计算距离矩阵的快捷方式
dist\u matrix


感谢@Jonas识别了“”

你能告诉我们你的例子的预期结果吗?如果数组具有统计意义,那么将距离平方相加而不是绝对值可能更有意义。它们是两个矩阵的特征值,其中一个参数略有变化。可能是平方距离更好,但问题仍然是计算上的挑战,因为所有排列都是问题所在。我曾想过开始对一个值进行排序,然后再进行下一个值的排序,但似乎找不到有效的解决方案(您是否忘记了行
v1=np.array后面的逗号([-0.99418-0.106364j,-1.005974-0.099054j
?否则我会得到一个异常。这是一个著名的问题,它被称为。所以dist是我的成本矩阵,线性求和赋值来自scipy.optimize,对吗?我会尝试实现它,看看它是否有效。顺便问一下,你如何在代码中定义从堆栈溢出中获得的解决方案。我应该正确吗在文档“Walter Tross的解决方案”或类似的内容中说些什么。是的,dist是
scipy.optimize.linear\u sum\u assignment()的成本矩阵,我现在将其重命名为
dist\u matrix
。至于属性,scipy和numpy的贡献者已经完成了真正的工作,因此不需要它。如果您想要指向解决方案的链接,它由其左下角的“共享”按钮提供。很高兴知道,但是……哇哦,
距离矩阵的类型是错误的(在您的情况下是复杂的)。它之所以有效,是因为其中所有复数都有0个虚部。我现在已经修复了它。类型是从第一个距离开始的,以保持通用性…我忘记了导入:-(