MATLAB创建基于Date列插入NaN的表

时间:2014-01-27 19:41:48

标签: matlab date concatenation

我的数据是每三天一次,但在我的单元格数组中,有时会缺少数天。如何在矩阵跳过一天并将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。

1 个答案:

答案 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。