我得到的数据如下所示。
[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 中 4 个不同行馈送到数据集 1 的 1 行中的最小距离吗?
如果这令人困惑,我深表歉意,但我的主要观点是,我不想遍历数组,并且我正在尝试找到更好的方法来解决此问题。
最后,我应该得到一个700 000行×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]
但是,当我尝试输入超过 1 个维度时,
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,1] 的数组), euc_dist([1,1,1,1],[2,2,2,2])] , ... ]
最佳答案
您可以为此使用广播:
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)
关于python - python numpy 数组的嵌套循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56816699/