2

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

import numpy as np
zvals = np.linspace(-5,5,10)
d = np.array([(0,0,z) for z in zvals])

我想计算数组中点的平方距离。使这项工作的非 numpy 方法是:

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

但是,我知道必须有某种方法可以通过一次调用 dot 来做到这一点,对吧?话虽如此,既不

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

或者

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

给我想要的。我很愚蠢,我意识到,但请在这里启发我。谢谢!

4

3 回答 3

7

编辑:从 NumPy 1.9 开始,看起来 inner1d 可能更快。(感谢 Nuno Aniceto 指出这一点):

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

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


如果你有 NumPy 1.6 或更高版本,你可以使用np.einsum

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
于 2013-06-30T14:06:29.983 回答
4

点积函数非常快,对于非常简单的东西甚至可以击败np.einsum(这是一个你绝对应该学会使用的了不起的函数)。Numpy 有一个隐藏的小宝石 ,inner1d它在其参数的最后一个维度上进行点积,并带有广播。您可以按如下方式使用它:

from numpy.core.umath_tests import inner1d
inner1d(a, a)
于 2013-06-30T14:36:49.373 回答
1

我不确定是否有一种巧妙的方法可以将普通的点积方法插入更大的数组中。相反,我通常这样做:

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 数组返回行而不是单个矩阵条目。

于 2013-06-30T14:03:02.070 回答