python numpy数组的嵌套循环

python numpy数组的嵌套循环,python,numpy,Python,Numpy,我得到的数据如下所示 [column 1] [column 2] [column 3] [column 4] [column 5] [row 1] (some value) [row 2] [row 3] ... [row 700 000] 第二个数据集看起来完全相同,但行数较少,约为4行。 我想做的是计算数据集1和2中每个数据之间的欧几里德距离,并找到4的最小值,如下所示: 然后对剩余的700000行数据重复此操作。我知道迭代n

我得到的数据如下所示

                [column 1]   [column 2]   [column 3]   [column 4]   [column 5]
[row 1]        (some value)
[row 2]
[row 3]
...
[row 700 000]
第二个数据集看起来完全相同,但行数较少,约为4行。 我想做的是计算数据集1和2中每个数据之间的欧几里德距离,并找到4的最小值,如下所示:

然后对剩余的
700000行
数据重复此操作。我知道迭代
numpy
数组是不可取的,因此有没有办法计算从数据集2到数据集1的1行馈送的4个不同行的最小距离

如果这让人困惑,我深表歉意,但我的主要观点是我不希望遍历数组,我正试图找到一种更好的方法来解决这个问题

最后,我应该返回一个700000行乘1列的数据,该数据具有数据集2的4个绿色框中的最佳(最低)值

import numpy as np

a = np.array([ [1,1,1,1] , [2,2,2,2] , [3,3,3,3] ])
b = np.array( [ [1,1,1,1] ] )

def euc_distance(array1, array2):
    return np.power(np.sum((array1 - array2)**2, axis = 1) , 0.5)
print(euc_distance(a,b))
# this prints out [0 2 4]
但是,当我尝试输入多个维度时

a = np.array([ [1,1,1,1] , [2,2,2,2] , [3,3,3,3] ])
b = np.array( [ [1,1,1,1] , [2,2,2,2] ] )

def euc_distance(array1, array2):
    return np.power(np.sum((array1 - array2)**2, axis = 1) , 0.5)
print(euc_distance(a,b))
# this throws back an error as the dimensions are not the same

我正在寻找一种方法,使其成为一种3D数组,在这里我得到的数组
[[euc_dist([1,1,1,1],[1,1,1]),euc_dist([1,1,1,1],[2,2,2,2,2]),…][/code>无法测试它,但这应该可以让你假设标准化的正数据。
np.argmax(np.matmul(a,b.T),轴=1)

对我以前的文章没有详细阐述。 如果性能仍然是一个问题,您可以使用以下方法代替您的方法:

b = np.tile(b, (a.shape[0], 1, 1))
a = np.tile(a, (1, 1, b.shape[1])).reshape(b.shape)
absolute_dist = np.sqrt(np.sum(np.square(a - b), axis=2))

它产生完全相同的结果,但在600000行上的运行速度比生成器快20倍。

谢谢大家的帮助,不过我想我已经通过使用简单的列表理解解决了自己的问题。我把事情复杂化了!通过这样做,我基本上减少了一半以上呈指数增长的时间,而不是迭代每个数据

我所做的是
c=np.数组([euc_距离(val,b)表示a中的val])

谁知道这个问题会有这么简单的解决办法

您可以为此使用广播:

a = np.array([
    [1,1,1,1],
    [2,2,2,2],
    [3,3,3,3]
])
b = np.array([
    [1,1,1,1],
    [2,2,2,2]
])

def euc_distance(array1, array2):
    return np.sqrt(np.sum((array1 - array2)**2, axis = -1))

print(euc_distance(a[None, :, :], b[:, None, :]))
# [[0. 2. 4.]
#  [2. 0. 2.]]
比较您大小的数据集的时间:

a = np.random.rand(700000, 4)
b = np.random.rand(4, 4)

c = euc_distance(a[None, :, :], b[:, None, :])
d = np.array([euc_distance(a, val) for val in b])
e = np.array([euc_distance(val, b) for val in a]).T

np.allclose(c, d)
# True
np.allclose(d, e)
# True

%timeit euc_distance(a[None, :, :], b[:, None, :])
# 113 ms ± 4.56 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit np.array([euc_distance(a, val) for val in b])
# 115 ms ± 4.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit np.array([euc_distance(val, b) for val in a])
# 7.03 s ± 216 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

这是你想要的吗嗨,谢谢你的帮助。但遗憾的是,这不是我想要的。你能添加一些示例数据,这样我们就可以自己测试了吗?700k数组中可能有20行,第二个datasetHi中有4行,因此从我的图片中,框1是行,每行有5列,值为2,3,4,6,7。绿色盒子也是如此。这里的问题是,在不迭代ITI的情况下,能够访问黑盒的值,谢谢你的回答,但我在寻找每个绿盒和黑盒之间的欧几里德距离,然后找到4个绿盒的最小距离,而不是矩阵乘法。得到的矩阵应该是700000行乘1列。这里的matmul得到700k*4,argmax得到700k*1。我的方法的问题是,它只是解决方案的一半,因为它没有考虑向量大小。要解决这个问题,在执行argMIN之前,必须将matmul结果除以相应向量的欧几里德长度的Produkt。我不是坐在电脑前,所以不能写表达式。还有另一种动手的方法。您可以使用np.tile将两个框重塑为4*700k*5,然后逐个元素进行减法。您好,我用一些代码编辑了我的问题,希望能澄清我的问题您好,我还包括了上面的一个示例。如果性能仍然是一个问题,您也可以尝试一下。您好,谢谢您的帮助!我的最终结果应该是一个[[0.2.][2.0.][4.2.]]数组,与你的相反。然而,我对代码做了一些修改,并通过输入euc_距离(a[:,None,:],b[None,:,:])得到了相同的结果。也许你可以解释一下广播是如何工作的?谢谢或者你可以简单地转换输出?我刚刚读过,但我似乎无法将它与代码的工作方式联系起来。顺便说一句,当迭代较大的循环时,我遇到了一个内存错误,这可能是执行此类切片时的限制之一吗?是的,广播将首先计算所有值,然后再进行求和。在本例中,
c
将暂时消耗比
d
多4倍的内存。您好,如果我错了,请纠正我,我自己做了一些学习,如果我没有错,您尝试做的是首先将阵列转换为3D,以便可以一起广播形状?顺便说一句,设置轴=-1有什么作用?它是否将尺寸从三维减少到二维?