以下是我正在使用的代码 -
mu = mean(X);
sigma = std(X);
for iter = 1:size(X, 1)
X_norm(iter,:)=((X(iter,:)-mu)./sigma)
end
我想知道是否有办法在不使用循环并仅使用基本运算符的情况下执行此操作,我可以通过这些运算符添加X中的每一行并将其除以sigma。
X和X_norm是矩阵。 我发现的一种方法是 - (虽然它使用函数)
one= ones(size(X, 1), 1);
X_norm = (X - one*(mean(X)))./(one*std(X));
请注意,我想了解有关使用基本操作符的更多信息,因此请不要提供任何库或工具包。
如果您要发布一个函数,也可以发布它的实现
答案 0 :(得分:3)
使用bsxfun
-
X_norm = bsxfun(@rdivide,bsxfun(@minus,X,mu),sigma)
您还可以使用ones()
与心爱的运算符:
进行复制,如Loren's blog
中所述,然后执行所述操作,就像这样 -
M = size(X,1);
X_norm = (X - mu(ones(M,1),:))./sigma(ones(M,1),:)
为了表现,我会随时使用bsxfun
!
答案 1 :(得分:3)
注意: @Divakar使用bsxfun
发布了一个非常优雅的答案,我建议使用这种方法。不过,我发布了这个答案(因为我已经在发布其他答案时已经写了大部分内容),所以你可以看到现有代码出了什么问题。
由于您的目标是将矩阵X
的每个行规范化为零均值和方差1,因此您的版本无法按预期工作。正如@Dan在评论中所说,通过使用/
进行除法,您可以在两个行向量之间进行矩阵划分,从而创建标量作为结果。因此,循环的输出是一个n x 1列向量(我不知道它实际包含的是什么......)。
首先,要意识到mean
返回一个行向量,其中每个条目都包含相应列的平均值。要逐行标准化,您必须获取每个行的平均值,这可以通过mean(X,2)
完成。 std
也是如此,即使用std(X,[],2)
。
mu = mean(X,2);
sigma = std(X,[],2);
使用for循环的版本现在是
X_norm = zeros(size(X));
for k= 1:size(X, 1)
X_norm(k,:) = (X(k,:)-mu(k)) ./ sigma(k);
end
即。遍历所有行并减去行的平均值,然后除以标准差。
通过使用mu(k)
,您可以为每一行使用正确的mean / std dev。
另外,出于性能原因,请不要忘记预先分配矩阵X_norm
。
答案 2 :(得分:2)
使用repmat
的另一种解决方案是
(X - repmat(mu, length(X), 1)) ./ repmat(sigma, length(X), 1)
这可能比bsxfun
更容易理解。我已发布此解决方案,以证明您需要执行您需要复制向量的操作mu
和sigma
。 :
无法使用repmat
。
虽然,我建议使用bsxfun
。
答案 3 :(得分:2)
如果您拥有Statistics Toolbox,则可以使用内置函数zscore()
X_norm = zscore(X);