gpt4 book ai didi

matlab - 在 MATLAB 中忽略 NaN 时从累积行值计算平均值

转载 作者:太空宇宙 更新时间:2023-11-03 19:24:50 25 4
gpt4 key购买 nike

我正在寻找有关如何优雅地解决以下问题的建议。虽然在我的具体情况下性能不是问题,但我很感激有关良好做法的评论。

提前致谢!

简短版:

我试图根据某种逻辑对矩阵行进行平均,同时忽略 NaN 值。我目前拥有的代码无法按照我想要的方式处理 NaN 值。

长版:

我的数据是按以下方式构建的:

  • “箱”的单个(第一)列。每个 bin 的行数不是恒定的。箱子不必是整数。行已预先排序。
  • 可变数量的数据列,可能包括 NaN。

这是一个例子:

DATA = [...
180 NaN NaN 1.733
180 NaN NaN 1.703
200 0.720 2.117 1.738
200 0.706 2.073 1.722
200 0.693 2.025 1.723
200 NaN NaN 1.729
210 NaN NaN 1.820
210 NaN NaN 1.813
210 NaN NaN 1.805
240 NaN NaN 1.951
240 NaN NaN 1.946
240 NaN NaN 1.946
270 NaN NaN 2.061
270 NaN NaN 2.052
300 0.754 2.356 2.103
300 0.758 2.342 2.057
300 NaN NaN 2.066
300 NaN NaN 2.066 ];

期望的结果是一个矩阵,它在第一列中包含唯一的“bins”,在其余列中表示“未被 NaN 破坏”,例如:

  • 如果对于特定的列+bin,只有 NaN(在上面的示例中:第一个数据列+bin 210)- 结果将为 NaN。
  • 如果对于特定的列+bin,混合了 NaN 和数字,则结果将是有效数字的平均值。在上面的例子中:第一个数据列+bin 200 应该给出 (0.720+0.706+0.693)/3=0.7063——注意这个列+bin 被 3(而不是 4)除。

这是上述示例的预期结果:

RES = [...
180 NaN NaN 1.718
200 0.7063 2.072 1.728
210 NaN NaN 1.812
240 NaN NaN 1.948
270 NaN NaN 2.056
300 0.756 2.349 2.074 ];

到目前为止我尝试了什么:

这是我设法从多个来源编译的一些代码。它适用于仅包含 NaN 或数字的 column+bin。

nDataCols=size(DATA,2)-1;
[u,m,n] = unique(DATA(:,1));
sz = size(m);
N=accumarray(n,1,sz);

RES(length(u),nDataCols) = 0; %Preallocation

for ind1 = 1:nDataCols
RES(:,ind1)=accumarray(n,DATA(:,ind1+1),sz)./N;
end

RES= [u,RES];

这是我目前得到的:

RES = [...
180 NaN NaN 1.718
200 NaN NaN 1.728
210 NaN NaN 1.812
240 NaN NaN 1.948
270 NaN NaN 2.056
300 NaN NaN 2.074 ];

附注

  1. 如果有任何机会使用电子表格软件(例如 MS Excel)更容易做到这一点 - 我很想听听想法。
  2. 在每列的基础上进行计算是我目前关于如何处理这个问题的想法。我只是想知道是否有一种方法可以将其概括为立即获取完整的矩阵。

最佳答案

一种可能的方法:在第一列中查找更改(利用它已预先排序的事实)并应用 nanmean到每个行 block :

ind = find(diff([-inf; (DATA(:,1)); inf])~=0); %// value changed: start of block
r = arrayfun(@(n) nanmean(DATA(ind(n):ind(n+1)-1,:)), 1:numel(ind)-1, 'uni', 0);
RES = vertcat(r{:});

您可以用显式循环替换 arrayfun。那may be faster ,并避免单元引入的开销:

ind = find(diff([-inf; (DATA(:,1)); inf])~=0); %// value changed: start of block
RES = zeros(numel(ind)-1, size(DATA,2)); %// preallocate
for n = 1:numel(ind)-1 %// loop over blocks
RES(n,:) = nanmean(DATA(ind(n):ind(n+1)-1,:));
end

您的方法也可以使用。您只需要使用 nanmean 函数的句柄调用 accumarray。这不需要对第一列进行预排序。

nDataCols = size(DATA,2)-1;
[u, ~, n] = unique(DATA(:,1));
RES = zeros(length(u), nDataCols); %// Preallocation
for ind1 = 1:nDataCols
RES(:,ind1) = accumarray(n, DATA(:,ind1+1), [], @nanmean);
end
RES = [u, RES];

关于matlab - 在 MATLAB 中忽略 NaN 时从累积行值计算平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24724246/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com