>假设我有一个由 tt 显示的日期向量和一个对应于 aa 的相应数据系列。例如:
dd = datestr(datenum('2007-01-01 00:00','yyyy-mm-dd HH:MM'):1/24:...
datenum('2011-12-31 23:00','yyyy-mm-dd HH:MM'),...
'yyyy-mm-dd HH:MM');
tt = datevec(datenum(dd,'yyyy-mm-dd HH:MM'));
tt(1002,:) = [];
aa = rand(length(tt),1)
如何确保小时和天数在年份之间保持一致?
例如,我只想保留年份之间相同的时间,例如
2009-01-01 01:00
将相同
2010-01-01 01:00
广告等等。
如果一年的测量值为
2009-01-01 02:00
但是 yyyy-01-01 02:00
在其他年份不存在,这个时间应该重新删除。
我希望返回 tt 和 aa,其中只保留年份之间一致的时间。 怎么能做到这一点?
我正在考虑首先找到独特年份的指数:
[~,~,iyears] = unique(tt(:,1),'rows');
然后查找唯一月、日和小时的索引,如下所示:
[~,~,iid] = unique(tt(:,2:4),'rows');
但我不确定如何组合这些以提供所需的输出?
下面的解决方案使用循环将数据存储在单元化数组中,这可能效率低下,但除非你的数据集很大(很多很多年(,否则它应该可以完成这项工作。一般的想法是将数据集分解为年。我将结果的时间向量存储在单元格数组中,因为它们可能不会具有相同的长度。然后,我对所有时间向量进行设置交集,以获得公共时间的向量。从那里开始,它是直截了当的。
years = unique(tt(:,1), 'rows');
% Put the "sub-times" of each year into cell array
for ii = 1:length(years)
times_each_year{ii} = tt(tt(:,1)==years(ii),2:end);
end
% Do intersection of all "sub-times" sets
common_times = times_each_year{1};
for ii = 2:length(years)
common_times = intersect(common_times, times_each_year{ii},'rows');
end
% Find and delete the points that are not member of the "sub-times":
idx = ~ismember(tt(:,2:end),common_times,'rows');
deleted_points = datestr(tt(idx,:)); % for later review
tt(idx,:) = [];
但是,请注意,deleted_points
向量包含的点数比预期的要多。那是因为2008年是闰年,所有的点都与2月相对应。删除了第29个。
如果您的数据被夏令时"污染",另一个这样的奇怪情况可能会等着您。
代码
a1 = str2num(datestr(tt,'mmddHHMM')); %// If in your data minutes are always 00, you can use 'mmddHH' instead and save some runtime
k1 = unique(a1);
gt1 = histc(a1,k1);
valid_rows = ismember(a1,k1(gt1==max(gt1)));
new_tt = tt(valid_rows,:); %// Desired tt output
new_aa = aa(valid_rows,:); %// Desired aa output
解释
为了理解它是如何工作的,让我们在微观层面上测试代码。让我们假设一些与tt
相对应的小数据 -
data1 = [4 5 1 4 5 1 4 5 6]
data1
是在几组上收集的数据,类似于tt
,当这四个参数组合成一个参数时,它包含几年的数据,包括月、日期、小时和分钟。
人们可以注意到它将表示来自三个集合/年的数据,数据为 {4,5}
、{1,4,5}
和 {1,4,5,6}
。我们的工作是找出所有三年/数据集中重复data1
值。因此,最终输出必须{4,5}
。
让我们看看如何对此进行编码。
步骤 1:获取唯一值
unique_val = unique(data1)
我们会 - [1 4 5 6]
步骤 2:获取数据中唯一值的计数
count_unique_val = histc(data1,unique_val)
输出为 - [2 3 3 1]
第 3 步:从唯一值数组中获取索引,其中它们的计数等于最大计数,指示这些是在所有集合中重复的唯一值。
index1 = count_unique_val==max(count_unique_val)
输出显示为 - [0 1 1 0]
步骤 4:获取这些"一致"的唯一值
consistent_val = unique_val(index1)
给了我们 - [4 5]
,这就是我们正在寻找的。
第 5 步:最后获取存在一致数据的索引,以后可用于选择具有"一致"数据的行。
index_consistent_val = ismember(data1,consistent_val)
输出是 - [1 1 0 1 1 0 1 1 0]
,这也是有道理的。
请注意,在原始代码中,a1 = str2num(datestr(tt,'mmddHHMM'));
从月、日期、小时和分钟四个参数中获取单个参数,如前面的评论中所述。