找到时间序列中的独特时间

时间:2014-05-23 12:11:23

标签: matlab vector

假设我有一个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');

但我不确定如何将这些结合起来以提供所需的输出?

2 个答案:

答案 0 :(得分:0)

下面的解决方案使用循环将数据存储在一个单元化的数组中,这可能是低效的,但除非您的数据集很大(有很多年),否则它应该完成这项工作。一般的想法是将数据集分解成多年。我将生成的时间向量存储在单元格数组中,因为它们可能不会具有相同的长度。然后我做了所有时间向量的集合交集,以获得常见的向量。从那里它是直截了当的。

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年是闰年,所有的积分都与Febr相对应。第29次被删除。

如果您的数据被夏令时“污染”,可能会有另外一种奇怪的现象。

答案 1 :(得分:0)

<强>代码

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'));会从月份,日期,小时和分钟这四个参数中获取单个参数,如前面的评论所述。