我可以通过在 matlab 中使用 : 运算符来避免规范化数据时的 for 循环吗?

Can I avoid the for loop in normalizing data by using : operator in matlab?

这是我使用的代码-

mu = mean(X);
sigma = std(X);

for iter = 1:size(X, 1)
  X_norm(iter,:)=((X(iter,:)-mu)./sigma)
end

我想知道是否有一种方法可以在不使用循环并仅使用基本运算符的情况下执行此操作,通过这种方法我可以将 X 中的每一行添加 mu,然后将每一行除以 sigma。

X 和 X_norm 是矩阵。 我发现的一种方法是 - (尽管它使用函数 ones )

one= ones(size(X, 1), 1);
X_norm = (X - one*(mean(X)))./(one*std(X));

请注意,我想了解有关使用基本运算符的更多信息,因此请不要推荐任何库或工具包。

如果你要post一个函数,post它的实现也是如此

使用bsxfun-

X_norm = bsxfun(@rdivide,bsxfun(@minus,X,mu),sigma)

你也可以使用ones() with your beloved operator : for replication as stated in Loren's blog然后执行规定的操作,像这样-

M = size(X,1);
X_norm = (X - mu(ones(M,1),:))./sigma(ones(M,1),:)

为了性能,我会选择 bsxfun 任何一天!

注意: @Divakar 使用 bsxfun 发布了一个非常优雅的答案,我建议使用该方法。尽管如此,我还是发布了这个答案(因为我在发布其他答案时已经写了大部分),因此您可以看到现有代码有什么问题。

由于您的目标是将矩阵 X 的每个 归一化为零均值和方差 1,因此您的版本无法按预期工作。正如@Dan 在评论中所说,通过使用 / 进行除法,您可以在两个行向量之间进行矩阵除法,从而创建一个标量。因此,循环的输出是一个 n x 1 列向量(我不知道它实际包含什么...)。

首先,实现mean returns a row vector, where each entry contains the mean of the corresponding column. To normalize row-wise, you have to get the mean of each row, which can be done by mean(X,2). The same goes for 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

使用 repmat 的另一个解决方案是

(X - repmat(mu, length(X), 1)) ./ repmat(sigma, length(X), 1)

这可能比 bsxfun 更容易理解。我已经发布了这个解决方案来证明要执行您想要的操作,您需要复制向量,musigmarepmat 可以用于此,: 不能。

补充阅读:Colon Operator in MATLAB


不过,我建议使用 bsxfun

如果你有 Statistics Toolbox, you can use the built-in function zscore()

X_norm = zscore(X);