1

次の形式の時系列があります。

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)

次に、2番目の列(2008年2月):

(first 01-Feb-2008 data value):(data value immediately preceding the first 01-Mar-2008 value)

等...

私が考えていたが、まとめる方法がわからないいくつかのアイデア:

  1. すべてのシリアル時刻番号(例:733408.33)を次の文字列に変換しますdatestr
  2. strmatch('01-January-2008',DatesInChars)2008年1月1日に対応する行のインデックスを検索するために使用します
  3. トリッキーな部分(?)TransformedData(:,i) = OriginalData(start:end):?end = strmatch(1) - 1およびstart = 1。次にstart、ループの最後でに変更し、strmatch(1)ステップ2を再度実行して、次の「開始インデックス」を見つけ、end「新規」に変更しstrmatch(1)-1ますか?

速度を最適化するといいでしょう。約200万回サンプリングされたデータに適用します。

ありがとう!

4

3 に答える 3

3

histcリストでは、2 番目のパラメーターとして月の最後の日のリストを使用します (注: histc2 つの戻り関数で使用します)。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)))
于 2012-11-27T10:36:09.287 に答える
0

timeVals各データの時間値を保持するNx1二重ベクトルがあると仮定します。dataNx1アレイでもあると仮定します。また、時間に応じて並べ替えられていると仮定datatimeValsます。つまり、サンプルは、取得された時間に応じて並べ替えられます。

どうですか:

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)を示します。

于 2012-11-27T11:46:22.203 に答える
0

等間隔ではない日付番号を並べ替えたと仮定すると、ここで行う方法は、関連するデータをcell 配列に配置することです。これにより、各エントリは翌月に対応し、異なる量の要素を保持できるようになります。

これを非常に効率的に行う方法は次のとおりです。

% 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
于 2012-11-27T10:31:36.187 に答える