【问题标题】:element wise operation - MATLAB逐元素操作 - MATLAB
【发布时间】:2011-12-08 15:24:00
【问题描述】:

我在 MATLAB 中有一个矩阵,可以说:

a = [
  89  79  96  
  72  51  74  
  94  88  87  
  69  47  78
]

我想从每个元素中减去其列的平均值,然后除以该列的标准差。我怎样才能以一种可以在不使用循环的情况下实现到任何其他矩阵的方式来做到这一点。

谢谢

【问题讨论】:

标签: matlab matrix


【解决方案1】:

您还可以使用统计工具箱中的ZSCORE 函数:

result = zscore(a)

其实它下面调用的是BSXFUN,但是注意不要除以零标准差(可以自己看源码:edit zscore

【讨论】:

    【解决方案2】:

    您可以使用repmat 使您的平均/标准向量与原始矩阵的大小相同,然后像这样使用直接计算:

    [rows, cols] = size(a); %#to get the number of rows
    
    avgc= repmat(avg(a),[rows 1]); %# average by column, vertically replicated by number of rows
    stdc= repmat(std(a),[rows 1]); %# std by column, vertically replicated by number of rows
    %# Here, a, avgc and stdc are the same size
    result= (a - avgc) ./ stdc;
    

    编辑:

    mathworks blog post,bsxfun 的解决方案来看更快并且消耗更少的内存(参见 acai 答案)。对于中等大小的矩阵,我个人更喜欢 repmat,它使代码更易于阅读和调试(对我而言)。

    【讨论】:

    • 我不同意使用 bsxfun 更难阅读或调试!事实上,任何一种用法都最好在前面加上注释,描述你在做什么。评论不需要时间来执行。与在调试中节省的时间相比,它们的编写成本很低,当您需要在明年更改代码时,或者当您需要修改从上周被跨城巴士碾过的家伙那里继承的代码时。
    • @woodchips 因此是“我个人更喜欢”。这是主观的,我编辑了我的答案以更加强调这一点。
    • 我的观点是,无论如何,使用 cmets 使代码可读,在这种情况下,没有正当理由(除了纯粹的惯性)来使用低效的旧样式。学习使用更好的形式作为一种习惯将改进您的代码。
    • 使用repmat,很明显哪个维度是正在“广播”的单例(使用 numpy 术语)。我只能想到一种比 bsxfun 更具可读性的方式,但正如@woodchips 所说,您始终可以使用评论。
    • 但是对于 matlab 新手来说,repmat 迫使您考虑要扩展哪些维度,因此与 bsxfun 相比,这是一个更好的练习
    【解决方案3】:

    如果您的版本支持bsxfun(除非您有非常旧的matlab 版本,否则可能是这种情况),您应该使用它,它比repmat 快得多,并且消耗的内存少得多。 你可以这样做:result = bsxfun(@rdivide,bsxfun(@minus,a,mean(a)),std(a))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      相关资源
      最近更新 更多