Python 如何匹配两个长度不等的numpy数组?

Python 如何匹配两个长度不等的numpy数组?,python,numpy,Python,Numpy,我有两个1D numpy阵列。长度不等。我想让元素对(array1_元素,array2_元素)彼此接近。让我们考虑下面的例子 a = [1,2,3,8,20,23] b = [1,2,3,5,7,21,35] 预期的结果是 [(1,1), (2,2), (3,3), (8,7), (20,21), (23,25)] 需要注意的是,5是单独存在的。它可以很容易地通过循环完成,但我有非常大的数组。我考虑使用最近的邻居。但感觉就

我有两个1D numpy阵列。长度不等。我想让元素对(array1_元素,array2_元素)彼此接近。让我们考虑下面的例子

    a = [1,2,3,8,20,23]
    b = [1,2,3,5,7,21,35]
预期的结果是

    [(1,1), 
    (2,2), 
    (3,3), 
    (8,7),
    (20,21),
    (23,25)]
需要注意的是,5是单独存在的。它可以很容易地通过循环完成,但我有非常大的数组。我考虑使用最近的邻居。但感觉就像用大炮杀了一只麻雀

有谁能提出一些优雅的解决方案吗

非常感谢。

使用算法怎么样?:)

评分矩阵将是微不足道的,因为两个数字之间的“距离”只是它们的差异

但这可能会让人感觉像是用坦克杀死了一只麻雀……

使用这个算法怎么样?:)

评分矩阵将是微不足道的,因为两个数字之间的“距离”只是它们的差异


但这可能会让人感觉像是用坦克杀死了一只麻雀…

我能想到的最好的方法是使用一个回路。如果python中的循环速度慢,可以使用Cython来加速代码。

我能想到的最好方法是使用循环。如果python中的循环很慢,可以使用Cython来加速代码。

我认为可以这样做:

  • 创建两个新的结构化数组,这样第二个索引为0或1,指示值属于哪个数组,即键
  • 连接两个数组
  • 沿第一个字段(值)对联合数组排序
  • 使用2个堆栈:遍历数组,将键为1的元素放在左侧堆栈中,当您穿过键为0的元素时,将它们放在右侧堆栈中。当使用键0到达第二个元素时,对于使用键0的第一个元素,请检查左右堆栈的顶部和底部,并获取最接近的值(可能具有最大距离),切换堆栈并继续

  • 排序应该是最慢的步骤,堆栈的最大总空间为n或m。

    我认为可以这样做:

  • 创建两个新的结构化数组,这样第二个索引为0或1,指示值属于哪个数组,即键
  • 连接两个数组
  • 沿第一个字段(值)对联合数组排序
  • 使用2个堆栈:遍历数组,将键为1的元素放在左侧堆栈中,当您穿过键为0的元素时,将它们放在右侧堆栈中。当使用键0到达第二个元素时,对于使用键0的第一个元素,请检查左右堆栈的顶部和底部,并获取最接近的值(可能具有最大距离),切换堆栈并继续

  • 排序应该是最慢的一步,堆栈的最大总空间为n或m。

    您可以使用内置的映射函数对执行此操作的函数进行矢量化。例如:

    ar1 = np.array([1,2,3,8,20,23])
    ar2 = np.array([1,2,3,5,7,21,35])
    def closest(ar1, ar2, iter):
        x = np.abs(ar1[iter] - ar2)
        index = np.where(x==x.min())
        value = ar2[index]
        return value
    
    def find(x):
        return closest(ar1, ar2, x)
    c = np.array(map(find, range(ar1.shape[0])))
    
    在上面的示例中,看起来您希望在值配对后排除它们。在这种情况下,您可以像这样在第一个函数中包含一个删除过程,但要非常小心数组1的排序方式:

     def closest(ar1, ar2, iter):
        x = np.abs(ar1[iter] - ar2)
        index = np.where(x==x.min())
        value = ar2[index]
        ar2[ar2==value] = -10000000
        return value
    

    您可以使用内置的map函数对执行此操作的函数进行矢量化。例如:

    ar1 = np.array([1,2,3,8,20,23])
    ar2 = np.array([1,2,3,5,7,21,35])
    def closest(ar1, ar2, iter):
        x = np.abs(ar1[iter] - ar2)
        index = np.where(x==x.min())
        value = ar2[index]
        return value
    
    def find(x):
        return closest(ar1, ar2, x)
    c = np.array(map(find, range(ar1.shape[0])))
    
    在上面的示例中,看起来您希望在值配对后排除它们。在这种情况下,您可以像这样在第一个函数中包含一个删除过程,但要非常小心数组1的排序方式:

     def closest(ar1, ar2, iter):
        x = np.abs(ar1[iter] - ar2)
        index = np.where(x==x.min())
        value = ar2[index]
        ar2[ar2==value] = -10000000
        return value
    

    您可以执行以下操作:

    a = np.array([1,2,3,8,20,23]) b = np.array([1,2,3,5,7,21,25]) def find_closest(a, sorted_b): j = np.searchsorted(.5*(sorted_b[1:] + sorted_b[:-1]), a, side='right') return b[j] b.sort() # or, b = np.sort(b), if you don't want to modify b in-place print np.c_[a, find_closest(a, b)] # -> # array([[ 1, 1], # [ 2, 2], # [ 3, 3], # [ 8, 7], # [20, 21], # [23, 25]]) a=np.数组([1,2,3,8,20,23]) b=np.数组([1,2,3,5,7,21,25]) def查找最近的(a,排序的b): j=np.searchsorted(.5*(sorted_b[1:][sorted_b[:-1]),a,side='right') 返回b[j] b、 sort()#或者,b=np.sort(b),如果您不想就地修改b 打印np.c_[a,查找最近的(a,b)] # -> #数组([[1,1], # [ 2, 2], # [ 3, 3], # [ 8, 7], # [20, 21], # [23, 25]])
    这应该很快。它的工作原理是
    searchsorted
    将为每个数字
    a
    找到
    b
    中的索引,该索引超过两个数字之间的中点,即最近的数字。

    您可以执行以下操作:

    a = np.array([1,2,3,8,20,23]) b = np.array([1,2,3,5,7,21,25]) def find_closest(a, sorted_b): j = np.searchsorted(.5*(sorted_b[1:] + sorted_b[:-1]), a, side='right') return b[j] b.sort() # or, b = np.sort(b), if you don't want to modify b in-place print np.c_[a, find_closest(a, b)] # -> # array([[ 1, 1], # [ 2, 2], # [ 3, 3], # [ 8, 7], # [20, 21], # [23, 25]]) a=np.数组([1,2,3,8,20,23]) b=np.数组([1,2,3,5,7,21,25]) def查找最近的(a,排序的b): j=np.searchsorted(.5*(sorted_b[1:][sorted_b[:-1]),a,side='right') 返回b[j] b、 sort()#或者,b=np.sort(b),如果您不想就地修改b 打印np.c_[a,查找最近的(a,b)] # -> #数组([[1,1], # [ 2, 2], # [ 3, 3], # [ 8, 7], # [20, 21], # [23, 25]])
    这应该很快。它的工作原理是,
    searchsorted
    将为每个数字
    a
    找到
    b
    中的索引,该索引超过两个数字之间的中点,即最近的数字。

    您对[1,3,5],[2,4]的期望是什么?还是有更多关于决胜局的信息?@amit,很好的观点。。。在这种情况下。。。订单将扮演角色[(1,2),(3,4)]将成为结果。谢谢您预期结果中的数字
    8.7
    来自哪里?你的输入数组总是这样预先排序吗?@wim-well。。。是的,数组总是这样排序…对不起,它是(8,7)。我会改正的。。。谢谢如果我理解,您希望选择一个配对,使得
    len(result)=min(len(a),len(b))
    sum([abs(p[1]-p[0])对于结果中的p])
    最小化。这是正确的吗?你对[1,3,5]、[2,4]的期望是什么?还是有更多关于决胜局的信息?@amit,很好的观点。。。在这种情况下。。。订单将扮演角色[(1,2),(3,4)]将成为结果。谢谢您预期结果中的数字
    8.7
    来自哪里?你的输入数组总是这样预先排序吗?@wim-well。。。是的,数组总是这样排序…对不起,它是(8,7)。我会改正的。。。谢谢如果我理解,您希望选择一个配对,使得
    len(result)=min(len(a),len(b))
    sum([abs(p[1]-p[0])对于结果中的p])
    最小化。“这是对的吗?”果冻豆。