首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >NumPy:如何快速归一化许多向量?

NumPy:如何快速归一化许多向量?
EN

Stack Overflow用户
提问于 2010-05-18 00:13:45
回答 6查看 40.8K关注 0票数 25

如何在NumPy中优雅地规范化向量列表?

下面是一个不起作用的例子:

代码语言:javascript
复制
from numpy import *

vectors = array([arange(10), arange(10)])  # All x's, then all y's
norms = apply_along_axis(linalg.norm, 0, vectors)

# Now, what I was expecting would work:
print vectors.T / norms  # vectors.T has 10 elements, as does norms, but this does not work

最后一个操作产生“形状不匹配:对象不能广播到单个形状”。

如何使用NumPy优雅地对vectors中的2D向量进行标准化?

编辑:为什么在向norms添加维度时上面的操作不起作用(根据我下面的答案)?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-05-18 00:21:10

好吧,除非我漏掉了什么,这是有效的:

代码语言:javascript
复制
vectors / norms

你的建议中的问题是广播规则。

代码语言:javascript
复制
vectors  # shape 2, 10
norms  # shape 10

形状的长度不一样!因此,规则是首先在left上将小形状扩展一

代码语言:javascript
复制
norms  # shape 1,10

您可以通过调用以下命令手动完成此操作:

代码语言:javascript
复制
vectors / norms.reshape(1,-1)  # same as vectors/norms

如果要计算vectors.T/norms,则必须手动进行整形,如下所示:

代码语言:javascript
复制
vectors.T / norms.reshape(-1,1)  # this works
票数 17
EN

Stack Overflow用户

发布于 2012-10-04 00:24:12

计算大小

我遇到了这个问题,并对你的规范化方法感到好奇。我使用一种不同的方法来计算大小。注意:我通常也会计算最后一个索引(在本例中是行,而不是列)的规范。

代码语言:javascript
复制
magnitudes = np.sqrt((vectors ** 2).sum(-1))[..., np.newaxis]

然而,通常情况下,我只是这样标准化:

代码语言:javascript
复制
vectors /= np.sqrt((vectors ** 2).sum(-1))[..., np.newaxis]

时间比较

我运行了一个测试来比较时间,发现我的方法快了相当多,但Freddie Witherdon的建议更快。

代码语言:javascript
复制
import numpy as np    
vectors = np.random.rand(100, 25)

# OP's
%timeit np.apply_along_axis(np.linalg.norm, 1, vectors)
# Output: 100 loops, best of 3: 2.39 ms per loop

# Mine
%timeit np.sqrt((vectors ** 2).sum(-1))[..., np.newaxis]
# Output: 10000 loops, best of 3: 13.8 us per loop

# Freddie's (from comment below)
%timeit np.sqrt(np.einsum('...i,...i', vectors, vectors))
# Output: 10000 loops, best of 3: 6.45 us per loop

但要注意,正如这篇StackOverflow answer所指出的那样,einsum没有进行一些安全检查,因此您应该确保vectorsdtype足以足够准确地存储幅度的平方。

票数 27
EN

Stack Overflow用户

发布于 2010-05-18 00:17:33

好的:NumPy的数组形状广播将维度添加到数组形状的左侧,而不是右侧。但是,可以指示NumPy在norms数组的右侧添加一个维度:

代码语言:javascript
复制
print vectors.T / norms[:, newaxis]

确实起作用了!

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2850743

复制
相关文章

相似问题

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