考虑以下示例:
Jday = datenum('2007-01-01 00:00','yyyy-mm-dd HH:MM'):1:...
datenum('2009-12-31 23:00','yyyy-mm-dd HH:MM');
Jday2 = datenum('2008-01-01 00:00','yyyy-mm-dd HH:MM'):1:...
datenum('2010-12-31 23:00','yyyy-mm-dd HH:MM');
Data{1} = [Jday;1+(length(Jday)-1).*rand(1,length(Jday))]';
Data{2} = [Jday2;1+(length(Jday)-1).*rand(1,length(Jday))]';
Data{3} = [Jday;1+(length(Jday)-1).*rand(1,length(Jday))]';
for i = 1:length(Data);
d_nan{i} = floor(1+(length(Jday)-1).*rand(1,100));
end
for i = 1:length(Data);
a(i) = length(d_nan{i});
for ii = 1:a(i);
Data{i}(d_nan{i}(ii),2) = nan;
end
end
在这个例子中,我有一个单元数组'Data',它包含三个单元格数组,每个单元格数组的第一列包含第二列中值的Julian日期。每个单元阵列中有许多纳米值。我想将每个单元格数组中的nan值替换为该特定julian日期的其他单元格中的平均值。我的问题很复杂,因为三个单元格没有同时显示数据(尽管Data {1}和Data {3}具有相同的天数。)如果julian日期在三个单元格之间相同,则可以通过使用isnan找到nans的位置,然后用其他行的nanmean(在其他单元格中)替换那些行。
有人能提出解决这个问题的有效方法吗?谢谢你的时间
答案 0 :(得分:1)
可能的解决方案是:
连接所有数据并找到NaN
值:
D = [vertcat(Data{:})];
nanidx = find(isnan(D(:, 2)));
对于连续矩阵k
中此类NaN
值的每个索引D
,找到具有相同日期的其他条目:
entries = find(D(:, 1) == D(k, 1));
过滤这些条目中的非NaN
值,并将位置NaN
的原始k
替换为平均值:
values = D(~isnan(D(entries, 2)) & ~ismember(entries, nanidx), 2);
D(k, 2) = mean(values);
将所有内容转换回单元格数组:
Data = mat2cell(D, cellfun('length', Data), 2)';
这是最终的,复制粘贴友好代码:
D = [vertcat(Data{:})];
nanidx = find(isnan(D(:, 2)));
for k = transpose(nanidx(:))
entries = find(D(:, 1) == D(k, 1));
values = D(~isnan(D(entries, 2)) & ~ismember(entries, nanidx), 2);
D(k, 2) = mean(values);
end
Data = mat2cell(D, cellfun('length', Data), 2)';
答案 1 :(得分:0)
这可能会解决您的问题,但这并不完全符合您的要求。在每个NaN值处,它将其替换为当天插入的值的平均值,并从插值中删除NaN。
for i = 1:3
for j = 1:length(Jday)
if isnan(Data{i}(j,2))
d = Data{i}(j,1);
Data{i}(j,2) = mean([ ...
interp1(Data{1}(find(~isnan(Data{1}(:,2))),1),Data{1}(find(~isnan(Data{1}(:,2))),2),d) ...
interp1(Data{2}(find(~isnan(Data{2}(:,2))),1),Data{2}(find(~isnan(Data{2}(:,2))),2),d) ...
interp1(Data{3}(find(~isnan(Data{3}(:,2))),1),Data{3}(find(~isnan(Data{3}(:,2))),2),d)]);
end
end
end
答案 2 :(得分:0)
不确定你是否看到了编辑(我是一个新用户,所以仍然在学习它是如何工作的),所以这里有一个解决方案可以做你所要求的并留下NaNs其他两个没有相同的日期
for i = 1:3
for j = 1:length(Jday)
if isnan(Data{i}(j,2))
d = Data{i}(j,1);
if (~isempty(find(Data{:,1}==d,1)) && ...
~isempty(find(Data{:,2}==d,1)) && ...
~isempty(find(Data{:,3}==d,1)))
Data{i}(j,2) = nanmean([ ...
Data{1}(find(Data{:,1}==d,1),2) ...
Data{2}(find(Data{:,2}==d,1),2) ...
Data{3}(find(Data{:,3}==d,1),2) ]);
end
end
end
end