我的数据是每三天一次,但在我的单元格数组中,有时会缺少数天。如何在矩阵跳过一天并将NaN放入样品测量单元格时使矩阵添加日期?
这是一个例子。我从4个站点中的每个站点放了2行。不同站点之间没有任何空行 - 为了清晰起见,它们就在那里。
Latitude Longitude SiteID Date Local Sample Measurement
43.435 -88.527778 027-0007 4/12/2007 4.3
43.435 -88.527778 027-0007 4/15/2007 9.3
43.060975 -87.913504 079-0026 4/12/2007 7.9
43.060975 -87.913504 079-0026 4/15/2007 11.3
45.203885 -90.600123 119-8001 4/12/2007 3.3
45.203885 -90.600123 119-8001 4/18/2007 9.5
43.020075 -88.21507 133-0027 4/12/2007 7.3
43.020075 -88.21507 133-0027 4/18/2007 5.6
这就是我想要的东西 - NaN是失踪日子的地方。如您所见,有不同的SiteID,因此我需要unique
分别浏览这些网站。
纬度经度SiteID日期本地样本测量
43.435 -88.527778 027-0007 4/12/2007 4.3
43.435 -88.527778 027-0007 4/15/2007 9.3
43.060975 -87.913504 079-0026 4/12/2007 7.9
43.060975 -87.913504 079-0026 4/15/2007 11.3
45.203885 -90.600123 119-8001 4/12/2007 3.3
45.203885 -90.600123 119-8001 4/15/2007 NaN
43.020075 -88.21507 133-0027 4/12/2007 7.3
43.020075 -88.21507 133-0027 4/15/2007 NaN
我开始这样的事情:
Set = datenum(2007,4,12):2:datenum(2007,10,15);
B = cat(2,PM25data(:,1:2), PM25data(:,6), PM25data(:,12), PM25data(:,16)); % Pull out only the columns needed
% B = {'Lat', 'Lon', 'SiteID', 'Date', 'Data'};
E = zeros(63, 5);
i = 1;
j = 1;
k = 1;
while i <= length(PM25site) && j <= length(E) && k <= length(B) % i = 1:4, j = 1:63, k = 1:32
if datenum(B(j,4)) ~= datenum(Set(j))
C = datenum(Set(j));
D = NaN;
E(j,:) = cat(2, str2double(B(j,1:3)), C, D);
j = j+1;
else
E(j,:) = str2double(B(k,:));
k = k+1;
j = j+1;
end
E(:,3) = PM25site(i);
i = i+1;
end
此代码未正确推进。它认为我没有正确编制索引并且else
不正确。它将我想要的东西放下来,但只替换前几行的零,然后一直保持零。
以下是一个示例部分:
45.203885 -90.600123 NaN 733144 3.3
45.203885 -90.600123 NaN 733146 NaN
45.203885 -90.600123 NaN 733148 NaN
45.203885 -90.600123 NaN 733150 NaN
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
我不知道这是否是接近它的最佳方法。我只是想在没有基于日期的数据的地方添加NaN。
答案 0 :(得分:1)
我认为您不需要使用while循环进行迭代。它会很慢,并且不利用MATLAB的矩阵功能。我就是这样做的。
all_dates = datenum(2007,4,12):2:datenum(2007,10,15);
% Note that we take the datenum of column 4 here now
B = cat(2,PM25data(:,1:2), PM25data(:,6), datenum(PM25data(:,12)), PM25data(:,16));
% First, generate a list of all siteIDs
[uID,ia] = unique(B(:,3));
% Now, preallocate the result matrix.
% Use NaNs, since we will overwrite all non-nan values in the final matrix
E = nan(length(all_dates)*length(uID),5);
% Set the date column
E(:,4) = repmat(all_dates,length(uID),1);
% Set the lat, long and ID columns
E(:,1) = reshape(repmat(B(ia,1)',length(all_dates),1),[],1);
E(:,2) = reshape(repmat(B(ia,2)',length(all_dates),1),[],1);
E(:,3) = reshape(repmat(uID',length(all_dates),1),[],1);
% Find the columns which we have data for
data_ind = ismember(E(:,3:4),B(:,3:4),'rows');
% And then set the data values
E(data_ind,5) = B(:,5);
大部分内容应该非常明确,但我只想澄清几点。
unique
的第二个输出生成一个索引矩阵,可用于查找原始矩阵中的唯一结果。我们的意思是B(ia,3)
生成所有唯一siteID的列表。此外,B(ia,1)
将生成这些siteID的纬度列表,并且类似于经度。
repmat(all_dates,length(uID),1)
重复所有日期的列表,就像我们有siteID一样。基本上,我们确保我们有一个包含所有日期+ siteID组合的列表。
reshape(repmat(uID',length(all_dates),1),[],1)
是一个简洁的小单行,它会生成重复的[1;1;1;2;2;2;3;3;3;...]
而不是[1;2;3;1;2;3;1;2;3;...]
的网站ID列表。
最后,我们使用'rows'选项让ismember
搜索date和siteID的组合。使用它,我们确定我们有数据的日期和siteID组合,并将此数据复制到我们的最终矩阵。我们没有数据的任何日期+ siteID将保留为NaN。