在matlab中使用nan值进行z得分(矢量化)

时间:2012-06-14 05:56:34

标签: matlab matrix loops vectorization nan

我正在尝试计算具有许多nan值的5000行向量的zscore。我必须多次计算所以我不想使用循环,我希望找到一个矢量化解决方案。

循环解决方案:

for i = 1:end
   vec(i,1) = (val(i,1) - nanmean(:,1))/nanstd(:,1)
end

部分矢量化解决方案:

zscore(vec(find(isnan(vec(1:end) == 0))))

但是这会返回一个向量,即原始向量的长度减去nan值。因此它与原始尺寸不同。

我想计算向量的zscore,然后在单词后插入缺失的数据。我必须这样做100次,因此我正在寻找一种快速的矢量化方法。

4 个答案:

答案 0 :(得分:1)

这是一个矢量化解决方案:

%使用NaN生成一些示例数据。

val = reshape(magic(4), 16, 1);
val(10) = NaN;
val(17) = NaN;

以下是代码:

valWithoutNaNs = val(~isnan(val));
valMean = mean(valWithoutNaNs);
valSD = std(valWithoutNaNs);
valZscore = (val-valMean)/valSD;

然后,列向量valZscore包含偏差(Z得分),并且NaNNaN值的val值是原始测量数据。

答案 1 :(得分:1)

对不起,这个答案迟了6个月,但对于遇到这个帖子的其他人来说:

接受的答案并没有完全矢量化,因为它没有做真正的zscore那么漂亮的事情:也就是说,沿着矩阵的特定维度做zscores。

如果你想同时计算大量矢量的zscores,正如OP所说的那样,最好的解决方案就是:

Z = bsxfun(@divide, bsxfun(@minus, X, nanmean(X)) , 
                   nanstd(X) );

要在任意维度上执行此操作,只需将维度放在nanmeannanstd内,bsxfun会处理其余维度。

nanzscore = @(X,DIM) bsxfun(@divide, bsxfun(@minus, X, nanmean(X,DIM)), ...
                                     nanstd(X,DIM));

答案 2 :(得分:0)

匿名函数:

nanZ = @(xIn)(xIn-nanmean(xIn))/ nanstd(xIn);

nanZ(vectorWithNans)

答案 3 :(得分:0)

以下匿名函数的矢量化版本(假设观察在行中,列中的变量):

nanZ = @(xIn)(xIn-repmat(nanmean(xIn),size(xIn,1),1))./repmat(nanstd(xIn),size(xIn,1),1);
nanZ(matrixWithNans)