首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对平方差的有效Numpy计算

对平方差的有效Numpy计算
EN

Stack Overflow用户
提问于 2015-09-05 16:01:44
回答 2查看 5.9K关注 0票数 7

下面的代码完全符合我的要求,即计算向量元素之间差异的成对平方和(在示例中长度为3),其中我有一个很长的序列(这里限制为5个)。所需的结果显示在底部。但是,执行过程有两个原因,让人感到疯狂:

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

2)显式“for”循环的明显必要性,我确信这就是为什么在我的大得多的数据集(长度为2904的百万向量)上执行需要几个小时。

是否有更有效的和/或仿生的方法来达到同样的效果?

代码语言:javascript
运行
复制
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.]]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-05 16:07:10

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

代码语言:javascript
运行
复制
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),那么(a - a.swapaxes(1,2))有形状(N, M, M)。确保您有足够的RAM来容纳这样大小的数组。页面交换也可以减缓计算到爬行。

如果您的内存太少,您将不得不将计算分解为块:

代码语言:javascript
运行
复制
m, _, n = a.shape
chunksize = 10**4
d = np.zeros((n,n))
for i in range(0, m, chunksize):
    b = a[i:i+chunksize]
    d += ((b - b.swapaxes(1,2))**2).sum(axis=0)

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

票数 6
EN

Stack Overflow用户

发布于 2015-09-05 16:21:58

如果您不介意对scipy的依赖,可以使用scipy.spatial.distance库中的函数:

代码语言:javascript
运行
复制
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.]])
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32415061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档