在NumPy中的均方根和矩阵/数组的复杂性

21

请问有没有numpy手册的相关章节,可以找到用于计算均方根的函数…(我知道可以使用np.mean和np.abs来完成这个任务..但是为什么没有内置函数呢?只是好奇,没有冒犯意思)

请问有没有人能够解释一下矩阵和数组的复杂性(只针对以下情况):

U是一个矩阵(T-by-N,或者说T cross N),Ue是另外一个矩阵(T-by-N) 我将k定义为一个numpy数组

U[ind,:]仍然是一个矩阵

按照以下方式 k = np.array(U[ind,:])

当我在ipython中打印k或者输入k

它会显示以下内容

K = array ([[2,.3 .....
              ......
                9]])

你会看到双方括号(我觉得这使它成为多维数组),这使它的形状为(1,N)。
但是我无法将其分配给以这种方式定义的数组。
l = np.zeros(N)
shape = (,N) or perhaps (N,) something like that

l[:] = k[:]
error:
matrix dimensions incompatible

有没有一种方法可以实现我想要做的向量赋值...请不要告诉我这样做 l = k(那就失去了目的...我在程序中得到了不同的错误..我知道原因..如果需要,我可以附上代码片段)

写一个循环是愚蠢的方式..但我暂时正在使用...

我希望我能够解释清楚..我面临的问题..

谢谢...


6
将来请不要在同一篇帖子中合并两个问题。这将使人们更容易回答,并且对于未来的用户来说也更容易找到信息。 - JoshAdel
1
如果您检查各种数组的形状属性(例如K.shapel[:].shape),您将看到数组的维度是否不兼容,并且它将为您提供有关如何纠正问题的线索。 - JoshAdel
1
确实是一个冗长的问题。正如已经指出的那样,如果你有两个问题,就分别问两个问题吧。无论如何,只要展示一下你的实际代码,很可能会得到建设性的建议。只是,你现在提问的方式(简单的问题)实际上使它们变得相当麻烦。谢谢。 - eat
1
请问您能否澄清您想要进行的RMS计算类型(可以通过引用方程式或链接到您使用的定义来说明)? - JoshAdel
@JoshAdel 谢谢您的评论...是的,从下一次开始...我会一次发布一个问题..关于什么类型的rms..好吧,我想取一个矩阵的一行并用一个数组减去它,然后我想平均这个结果序列(在均方意义上)..我知道我的问题很啰嗦,我认为这会帮助我表达我的问题..结果证明相反! - fedvasu
7个回答

87

对于RMS,我认为这是最清晰的解释:

from numpy import mean, sqrt, square, arange
a = arange(10) # For example
rms = sqrt(mean(square(a)))

代码的读取方式与你所说的一样:“均方根”。


5
我经常处理复杂数据,如果是这种情况,平方不够用。你需要像abs(a)**2这样的东西。 - Eric C.
1
确实。或者你可以使用a*conj(a),这应该更有效率,尽管我还没有进行基准测试。 - deprecated
这可能是我见过的非平凡算法最优雅的表述方式。而且它还很有用!太棒了。 - Walter Nissen
np.std(a) 不是做同样的事情吗? - Rainb
@Rainb:不,它们不一样,除非 np.mean(a) == 0.0 - deprecated
1
个人而言,我更喜欢避免从numpy库中导入每个函数。考虑使用"import numpy as np",然后使用"np.mean"、"np.sqrt"等。 - Mauricio Arboleda-Zapata

13

对于rms来说,我发现适用于小的x.size(~1024)和实数x最快表达式是:

def rms(x):
    return np.sqrt(x.dot(x)/x.size)

这似乎比linalg.norm版本快了两倍(在一个非常老的笔记本电脑上运行ipython %timeit)。

如果您想更适当地处理复杂数组,那么这个方法也可以:

def rms(x):
    return np.sqrt(np.vdot(x, x)/x.size)

然而,这个版本几乎和norm版本一样慢,并且只适用于扁平数组。


8
我不知道为什么它没有内置。我喜欢。
def rms(x, axis=None):
    return sqrt(mean(x**2, axis=axis))

如果您的数据中存在nans,则可以执行以下操作:
def nanrms(x, axis=None):
    return sqrt(nanmean(x**2, axis=axis))

3
我经常处理复杂数据,在这种情况下,仅使用平方是不够的。你需要像 abs(x)**2 这样的表达式,而不仅仅是 x**2 - Eric C.

8
对于RMS,怎么样?
norm(V)/sqrt(V.size)

2
点赞因为它很简洁,但规范是从 np.linalg 而不是直接从 np 导入,并且它没有可选的 axis 参数,这对于使 rms 函数更通用非常有用。 - dashesy
1
自从1.8.0版本以后,np.linalg.norm拥有了一个轴参数。 - a_guest

5

试试这个:

U = np.zeros((N,N))
ind = 1
k = np.zeros(N)
k[:] = U[ind,:]

1
小修正:应该是U = np.zeros((N,N)),否则会出现错误。 - JoshAdel
谢谢 highBandWidth 和 JoshAdel...这样就可以了...你能推荐一个我可以查看这种信息的参考资料吗?(我正在研究适用于Matlab用户的NumPy...这足够好吗?) - fedvasu
我主要是通过尝试使用scipy/numpy得到这个。 - highBandWidth
@chwi,N是您想要的矩阵的维数。它是一个数字,比如如果您想要一个5x5的矩阵,那么N就是5。 - highBandWidth

1

我在RMS中使用NumPy,让它也有一个可选的axis参数,类似于其他NumPy函数:

import numpy as np   
rms = lambda V, axis=None: np.sqrt(np.mean(np.square(V), axis))

0
如果您有复杂的向量并且正在使用pytorch,则矢量范数是在CPU和GPU上最快的方法:
import torch
batch_size, length = 512, 4096
batch = torch.randn(batch_size, length, dtype=torch.complex64)
scale = 1 / torch.sqrt(torch.tensor(length))
rms_power = batch.norm(p=2, dim=-1, keepdim=True)
batch_rms = batch / (rms_power * scale)

使用批处理vdot,如goodboy的方法,比上述方法慢60%。使用类似deprecated的方法的朴素方法比上述方法慢85%。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接