numpy行对平方行明智差异的总和没有for循环(只有api调用)

时间:2014-11-28 13:42:37

标签: python numpy matrix multidimensional-array

对于那些可以阅读Latex的人来说,这就是我想要计算的内容:

$$ k_ {xyi} = \ sum_ {j} \ left(\ left(x_ {i} -x_ {j} \ right)^ {2} + \ left(y_ {i} -y_ {j} \ right)^ {2} \ right)$$

其中x和y是矩阵A的行。

对于计算机语言,只有民间这将翻译为: k(x,y,i)= sum_j((xi - xj)^ 2 +(yi - yj)^ 2) 其中x和y是矩阵A的行。

所以k是一个3d矩阵。

这可以仅通过API调用完成吗? (没有循环)

这是测试启动:

import numpy as np
A = np.random.rand(4,4)
k = np.empty((4,4,4))
for ix in range(4):
    for iy in range(4):
        x = A[ix,]
        y = A[iy,]
        sx = np.power(x - x[:,np.newaxis],2)
        sy = np.power(y - y[:,np.newaxis],2)
        k[ix,iy] = (sx + sy).sum(axis=1).T

现在对于主编码器,请用numpy API调用替换两个for循环。

更新: 忘记提到我需要一种节省RAM空间的方法,我的A矩阵通常是20-30万平方。因此,如果您的答案不会创建巨大的临时多维数组,那就太棒了。

1 个答案:

答案 0 :(得分:4)

我会改变你的乳胶看起来更像下面的东西 - 它更不容易混淆imo:

enter image description here

由此我假设你的表达式中的最后一行应该是:

k[ix,iy] = (sx + sy).sum(axis=-1)

如果是这样,您可以按如下方式计算上述表达式:

Axij = (A[:, None, :] - A[..., None])**2
k = np.sum(Axij[:, None, :, :] + Axij, axis=-1)

以上首先扩展了内存密集型4D阵列。如果您通过引入新的for循环来担心内存,可以跳过此步骤:

k = np.empty((4,4,4))
Axij = (A[:, None, :] - A[..., None])**2
for xi in range(A.shape[0]):
    k[xi] = np.sum(Axij[xi, None, :, :] + Axij, axis=-1)

这会慢一些,但不会像你想象的那么多,因为你仍然在numpy中做了很多操作。您可以跳过3D Axij中间件,但同样会对性能造成影响。

如果你的矩阵在边缘真的是20k,你的3D输出将是64TB。你不会在numpy甚至内存中这样做(除非你有一个大规模的分布式内存系统)。