在时间序列的年份中查找唯一时间



>假设我有一个由 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'));从月、日期、小时和分钟四个参数中获取单个参数,如前面的评论中所述。

最新更新