两两平方差的有效Numpy计算

2024-04-29 15:12:37 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的代码正是我想要的,即计算向量元素之间的差的两两平方和(示例中的长度为3),我有一个很长的序列(这里限制为5个)。期望的结果显示在底部。 但是,由于以下两个原因,这项计划的实施让人感到困惑:

1)需要添加虚拟尺寸,将形状从(5,3)更改为(5,1,3),以避免广播问题,以及

2)显式的“for”循环显然是必要的,我确信这就是为什么在我更大的数据集(长度为2904的一百万个向量)上执行要花费数小时的原因。在

有没有更有效和/或Python式的方法来达到同样的效果?在

a = np.array([[ 4,  2,  3], [-1, -5,  4], [ 2,  1,  4], [-5, -1,  4], [6, -3,  3]])
a = a.reshape((5,1,3))

m = a.shape[0]
n = a.shape[2]
d = np.zeros((n,n))
for i in range(m):
    c = a[i,:] - np.transpose(a[i,:])
    c = c**2
    d += c

print d

[[   0.  118.  120.]
 [ 118.    0.  152.]
 [ 120.  152.    0.]]

Tags: 数据代码元素示例for尺寸np原因
2条回答

可以使用以下方法消除for循环:

In [48]: ((a - a.swapaxes(1,2))**2).sum(axis=0)
Out[48]: 
array([[  0, 118, 120],
       [118,   0, 152],
       [120, 152,   0]])

注意,如果a具有形状(N, 1, M),那么{}具有形状{}。确保有足够的内存来容纳这种大小的数组。页面交换也会降低计算速度。在

如果内存太少,则必须将计算分成块:

^{2}$

这是对整个数组执行计算和 逐行计算。如果有一百万行,而chunksize是10**4,那么循环只会有100次迭代,而不是100万次。 因此,它应该比逐行计算要快得多。选择允许在RAM中执行计算的chunksize的最大值。在

如果您不介意对scipy的依赖,可以使用^{}库中的函数:

In [17]: from scipy.spatial.distance import pdist, squareform

In [18]: a = np.array([[ 4,  2,  3], [-1, -5,  4], [ 2,  1,  4], [-5, -1,  4], [6, -3,  3]])

In [19]: d = pdist(a.T, metric='sqeuclidean')

In [20]: d
Out[20]: array([ 118.,  120.,  152.])

In [21]: squareform(d)
Out[21]: 
array([[   0.,  118.,  120.],
       [ 118.,    0.,  152.],
       [ 120.,  152.,    0.]])

相关问题 更多 >