我有以下格式的时间序列:
time data value
733408.33 x1
733409.21 x2
733409.56 x3
etc..
数据从2008年1月1日左右到2010年12月31日。 我想将数据分成每月长度的列。
例如,第一列(2008年1月)将包含相应的数据值:
(first 01-Jan-2008 data value):(data value immediately preceding the first 01-Feb-2008 value)
然后是第二栏(2008年2月):
(first 01-Feb-2008 data value):(data value immediately preceding the first 01-Mar-2008 value)
等等......
我一直在考虑的一些想法,但不知道如何拼凑起来:
datestr
strmatch('01-January-2008',DatesInChars)
查找与2008年1月1日对应的行的索引TransformedData(:,i) = OriginalData(start:end)
? end = strmatch(1) - 1
和start = 1
。然后在循环结束时将start
更改为strmatch(1)
,然后再次运行第2步以查找下一个“起始索引”并将end
更改为“新”strmatch(1)-1
?快速优化它会很好;我将把它应用于大约200万次采样的数据。
谢谢!
答案 0 :(得分:3)
我会使用histc
一个列表,列出一个月的最后几天作为第二个参数(注意:使用histc
和两个返回函数)。
可以使用datenum
或datevec
轻松创建边缘列表。
这样你就不会对字符串进行操作而你应该很快。
编辑: 结果为简单数据结构的示例(包括来自@Rody的一些代码):
% Generate some test times/data
tstart = datenum('01-Jan-2008');
tend = datenum('31-Dec-2010');
tspan = tstart : tend;
tspan = tspan(:) + randn(size(tspan(:))); % add some noise so it's non-uniform
data = randn(size(tspan));
% Generate list of edge
edge = [];
for y = 2008:2010
for m = 1:12
edge = [edge datenum(y, m, 1)];
end
end
% Histogram
[number, bin] = histc(tspan, edge);
% Setup of result
result = {};
for n = 1:length(edge)
result{n} = [tspan(bin == n), data(bin == n)];
end
% Test
% 04-Aug-2008 17:25:20
datestr(result{8}(4,1))
tspan(data == result{8}(4,2))
datestr(tspan(data == result{8}(4,2)))
答案 1 :(得分:0)
假设您已经排序了非等间距日期数,那么此处的方法是将相关数据放在单元格数组中,以便每个条目对应下个月,并且可以容纳不同数量的元素。
以下是如何非常有效地完成这项工作:
% generate some test times/data
tstart = datenum('01-Jan-2008');
tend = datenum('31-Dec-2010');
tspan = tstart : tend;
tspan = tspan(:) + randn(size(tspan(:))); % add some noise so it's non-uniform
data = randn(size(tspan));
% find month numbers
[~,M] = datevec(tspan);
% find indices where the month changes
inds = find(diff([0; M]));
% extract data in columns
sz = numel(inds)-1;
cols = cell(sz,1);
for ii = 1:sz-1
cols{ii} = data( inds(ii) : inds(ii+1)-1 );
end
请注意,很难确定cols
中的哪个条目属于哪个月,哪一年,所以这里是如何以更人性化的方式进行的:
% change this line:
[y,M] = datevec(tspan);
% and change these lines:
cols = cell(sz,3);
for ii = 1:sz-1
cols{ii,1} = data( inds(ii) : inds(ii+1)-1 );
% also store the year and month
cols{ii,2} = y(inds(ii));
cols{ii,3} = M(inds(ii));
end
答案 2 :(得分:0)
我假设你有一个timeVals
个Nx1双向量,它保存每个数据的时间值。假设data
也是Nx1数组。我还假设data
和timeVals
按时间排序:也就是说,您拥有的样本是根据拍摄时间排序的。
怎么样:
subs = @(x,i) x(:,i);
months = subs( datevec(timeVals), 2 ); % extract the month of year as a number from the time
r = find( months ~= [months(2:end), months(end)+1] );
monthOfCell = months( r );
r( 2:end ) = r( 2:end ) - r( 1:end-1 );
dataByMonth = mat2cell( data', r ); % might need to transpose data or r here...
timeByMonth = mat2cell( timeVal', r );
运行此代码后,您有一个单元格数组dataByMonth
,每个单元格包含与特定月份相关的所有数据。 timeByMonth
的相应单元格保存相应月份的数据的采样时间。最后,monthOfCell
告诉您每个单元格的月份数(1-12)。