Python 从numpy数组计算平方距离

Python 从numpy数组计算平方距离,python,numpy,Python,Numpy,我脑子有点问题,但我就是不能让它工作。我有一系列的距离: import numpy as np zvals = np.linspace(-5,5,10) d = np.array([(0,0,z) for z in zvals]) 我想计算数组中点的平方距离。实现这一目标的非关键方法是: d2 = np.array([np.dot(d[i,:],d[i,:]) for i in range(d.shape[0])]) 然而,我知道,一定有办法做到这一点,只需对dot进行一次调用,对吗?话虽如

我脑子有点问题,但我就是不能让它工作。我有一系列的距离:

import numpy as np
zvals = np.linspace(-5,5,10)
d = np.array([(0,0,z) for z in zvals])
我想计算数组中点的平方距离。实现这一目标的非关键方法是:

d2 = np.array([np.dot(d[i,:],d[i,:]) for i in range(d.shape[0])])
然而,我知道,一定有办法做到这一点,只需对dot进行一次调用,对吗?话虽如此,也不是

d2 = np.dot(d,d.T)


给我想要的。我知道我很愚蠢,但请在这里启发我。谢谢

我不确定是否有一种简单的方法可以将普通的点积方法放入一个更大的数组中。相反,我通常会:

d2 = n.sum(d*d,axis=1)
d*d当然是标准的点积运算,因为它只是数组中所有项的元素乘法。
axis=1
参数沿第二个轴求和(在打印阵列时水平),这是点积运算的第二部分

编辑:另外,忽略方法的一般不受欢迎性,您的行

d2 = np.array([np.dot(d[i,:],d[i,:]) for i in range(d.shape[0])])
可以简单

d2 = np.array([np.dot(row,row) for row in d])

当使用“for in-array”语法时,numpy数组返回的是行而不是单个矩阵项。

编辑:从numpy 1.9开始,inner1d可能会更快。(感谢努诺·安切托指出这一点):

注:始终在与预期用例类似的输入上为自己测试基准。结果可能因各种原因而不同,例如输入大小、硬件、操作系统、Python版本、NumPy版本、编译器和库(例如ATLAS、MKL、BLAS)


如果您有NumPy 1.6版或更高版本,您可以使用:






点积函数的速度非常快,对于真正简单的东西,它甚至可能超过np.einsum(这是一个非常好的函数,你一定要学会使用)。Numpy有一个隐藏的小gem,
inner1d
,它在参数的最后一个维度上进行点积,并进行广播。您可以按如下方式使用它:

from numpy.core.umath_tests import inner1d
inner1d(a, a)

Hmmm.np.diag(np.dot(d,d.T))似乎起作用。有更好的方法吗?很好!当我说我想让np.dot做这件事时,我说错了。我只想要一个纯粹的numpy解决方案,这就是您提供的。谢谢unutbu的答案是正确使用numpy语法的一个更好(更快!)的例子,我刚刚检查过,它看起来np.sum方法比np.diag one慢一点,比einsum慢很多。感谢您检查这个!哇!我以前没听说过艾因苏姆。谢谢。
np.einsum
总是得到+1!您可以根据
inner1d
添加计时吗?我现在不能确定时间,但我认为这可能是一个很好的竞争者。@Jaime:谢谢,Jaime。这对我来说是一个新的解决方案。我理解为什么它比
diag(dot(d,d.T))
快(因为这会进行不必要的计算),但您能解释一下为什么它比
sum(d**2)
快得多吗?@按位:部分是用Python编写的。在用C编写的情况下,
np.sum(d*d)
至少需要两个Python函数调用(
np.sum
d.\uuuuuuuuuuu
)<代码>np.einsum只使用一个。此外,
np.einsum
是专门为求乘积之和而设计的。我猜
np.einsum
没有分配一个形状
(n,3)
中间数组(如
d*d
所需);相反,它可以直接计算长度
n
1D结果。
In [9]:  %timeit -n 1000000 inner1d(d,d)
1000000 loops, best of 3: 1.39 µs per loop

In [14]: %timeit -n 1000000 einsum('ij,ij -> i', d, d)
1000000 loops, best of 3: 1.8 µs per loop
In [40]: %timeit np.einsum('ij,ij -> i', d, d)
1000000 loops, best of 3: 1.79 us per loop
In [46]: from numpy.core.umath_tests import inner1d

In [48]: %timeit inner1d(d, d)
100000 loops, best of 3: 1.97 us per loop
In [44]: %timeit np.sum(d*d, axis=1)
100000 loops, best of 3: 5.39 us per loop
In [41]: %timeit np.diag(np.dot(d,d.T)) 
100000 loops, best of 3: 7.2 us per loop
In [42]: %timeit np.array([np.dot(d[i,:],d[i,:]) for i in range(d.shape[0])])
10000 loops, best of 3: 26.1 us per loop
from numpy.core.umath_tests import inner1d
inner1d(a, a)