NumPy计算向量

[这种方式的缺点是，如果我想为`a-b`或更复杂的表达式计算它，我必须再做一行。 `c = a - b``np.inner(c, c)`代替`somewhat(a - b)`]

4 个答案:

``````numpy.linalg.norm(x, ord=2)
``````

`numpy.linalg.norm(x, ord=2)**2`为方

``````sqeuclidean = lambda x: np.inner(x, x)
``````

`np.inner``np.dot`利用BLAS例程，几乎肯定比标准元素乘法更快，然后求和。

``````In [1]: %%timeit -n 1 -r 100 a, b = np.random.randn(2, 1000000)
((a - b) ** 2).sum()
....:
The slowest run took 36.13 times longer than the fastest. This could mean that an intermediate result is being cached
1 loops, best of 100: 6.45 ms per loop

In [2]: %%timeit -n 1 -r 100 a, b = np.random.randn(2, 1000000)
np.linalg.norm(a - b, ord=2) ** 2
....:
1 loops, best of 100: 2.74 ms per loop

In [3]: %%timeit -n 1 -r 100 a, b = np.random.randn(2, 1000000)
sqeuclidean(a - b)
....:
1 loops, best of 100: 2.64 ms per loop
``````

`np.linalg.norm(..., ord=2)`在内部使用`np.dot`，并且与直接使用`np.inner`的效果非常相似。

``````import timeit

setup_code = """
import numpy as np
descriptors = np.random.rand(3000, 512)
desc = np.random.rand(512)
"""

norm_code = """
np.linalg.norm(descriptors - desc[None], axis=-1)
"""
norm_time = timeit.timeit(stmt=norm_code, setup=setup_code, number=100, )

einsum_code = """
x = descriptors - desc[None]
sqrd_dist = np.einsum('ij,ij -> i', x, x)
"""
einsum_time = timeit.timeit(stmt=einsum_code, setup=setup_code, number=100, )

norm_sqrd_code = """
distances = np.sum((descriptors - desc[None])**2, axis=1)
"""
norm_sqrd_time = timeit.timeit(stmt=norm_sqrd_code, setup=setup_code, number=100, )

print(norm_time) # 0.7688689678907394
print(einsum_time) # 0.29194538854062557
print(norm_sqrd_time) # 0.274090813472867

``````