1

毎日の日付、価格、時間 (すべて同じサイズのベクトル) の 3 つの列を持つマトリックスAがあります。1 日の時間に関連付けられた複数の価格があります。

以下のサンプルデータ:

A_dates =          A_hours=        A_prices=
[20080902         [9.698           [24.09
20080902          9.891             24.59
200080902         10.251            24.60 
20080903          9.584             25.63
200080903         10.45             24.96
200080903         12.12             24.78
200080904          12.95            26.98 
20080904           13.569           26.78
20080904]          14.589]          25.41]
  • 午前 9 時 30 分から午後 16 時までのほぼすべての分をカバーする、1 日あたり約 10,000 の価格の約 2 年間の日次データがあることを覚えておいてください。実際、最初のデータセット時間はミリ秒単位でした。次に、ミリ秒を時間に変換しました。14.589 のような時間を、3 つの異なる価格で 3 回繰り返しました。したがって、私は次のことを行いました:

    time=[A_dates,A_hours,A_prices]; [timeinhr,price]=consolidator(time,A_prices,'mean'); ここで、timeinhr はベクトル A_dates と A_hours の両方です

それぞれの平均価格を 14.589 時間とします。次に、.25 .50 .75 および整数時間の欠落時間について-補間したいと思います。

日付ごとに時間が繰り返され、「必要な」時間にない価格を直線的に補間する必要があります。ただし、もちろん、複数の日があるため、列で時間が繰り返される場合、コマンド interp1 を使用することはできません。だから、言って:

%# here I want hours in 0.25unit increments (like 9.5hrs)
new_timeinhr = 0:0.25:max(A_hours));

day_hour = rem(new_timeinhour, 24);

%# Here I want only prices between 9.5hours and 16hours
new_timeinhr( day_hour <= 9.2 | day_hour >= 16.1 ) = [];  

次に、1 日の一意のベクトルを作成し、for コマンドと if コマンドを使用して補間dailyし、新しい価格をベクトルに次々と積み上げたいと考えています。

days = unique(A_dates);
for j = 1:length(days);
    if A_dates == days(j)
       int_prices(j) = interp1(A_hours, A_prices, new_timeinhr);
    end;
end;

私のエラーは次のとおりです。

In an assignment A(I) = B, the number of elements in B and I must be the same.

どうすればint_prices(j)スタックに書き込むことができますか?

4

3 に答える 3

3

入力を単一の単調時間値に変換することをお勧めします。1 日を 1 として表すMATLABdatenum形式を使用します。これには多くの利点があります。組み込みの MATLAB 時刻/日付関数を取得し、 を介して日付/時刻として適切にフォーマットされたプロット ラベルを取得しdatetick、補間が機能します。テスト データがなければ、このコードをテストすることはできませんが、一般的な考え方は次のとおりです。

日付が 20080902 (yyyymmdd と仮定) として保存されているという新しい情報に基づいて、最初の変換コードを更新しました。また、A のレイアウトが混乱を招いているため、A の列をベクトルA_pricesA_hours、および と呼ぶことにしますA_dates

% This datenum vector matches A.  I'm assuming they're already sorted by date and time
At = datenum(num2str(A_dates), 'yyyymmdd') + datenum(0, 0, 0, A_hours, 0, 0);
incr = datenum(0, 0, 0, 0.25, 0, 0);  % 0.25 hour
t = (At(1):incr:At(end)).';       % Full timespan of dataset, in 0.25 hour increments

frac_hours = 24*(t - floor(t));        % Fractional hours into the day
t_business_day = t((frac_hours > 9.4) & (frac_hours < 16.1));  % Time vector only where you want it

P = interp1(At, A_prices, t_business_day);

繰り返しますが、テスト データがないため、コードをテストできません。datenum から読み取り可能な日付に戻すdatestrために使用して、日付変換コードをテストすることを強くお勧めします。

于 2012-06-07T13:53:32.043 に答える
1

@Peterで提案されているように、日/時をシリアル日付番号に変換することは間違いなく道です。彼のコード (私はすでに賛成しています) に基づいて、簡単な例を以下に示します。

最初に、あなたが説明したものに似た偽のデータを作成することから始めます(いくつかの欠落部分もあります):

%# three days in increments of 1 hour
dt = datenum(num2str((0:23)','2012-06-01 %02d:00'), 'yyyy-mm-dd HH:MM');   %#'
dt = [dt; dt+1; dt+2];

%# price data corresponding to each hour
p = cumsum(rand(size(dt))-0.5);

%# show plot
plot(dt, p, '.-'), datetick('x')
grid on, xlabel('Date/Time'), ylabel('Prices')

%# lets remove some rows as missing
idx = ( rand(size(dt)) < 0.1 );
hold on, plot(dt(idx), p(idx), 'ro'), hold off
legend({'prices','missing'})
dt(idx) = [];
p(idx) = [];

%# matrix same as yours: days,prices,hours
ymd = str2double( cellstr(datestr(dt,'yyyymmdd')) );
hr = str2double( cellstr(datestr(dt,'HH')) );
A = [ymd p hr];

%# let clear all variables except the data matrix A
clearvars -except A

次に、範囲全体で 15 分単位で価格データを補間します。

%# convert days/hours to serial date number
dt = datenum(num2str(A(:,[1 3]),'%d %d'), 'yyyymmdd HH');

%# create a vector of 15 min increments
t_15min = (0:0.25:(24-0.25))';                  %#'
tt = datenum(0,0,0, t_15min,0,0);

%# offset serial date across all days
ymd = datenum(num2str(unique(A(:,1))), 'yyyymmdd');
tt = bsxfun(@plus, ymd', tt);                   %#'
tt = tt(:);

%# interpolate data at new datetimes
pp = interp1(dt, A(:,2), tt);

%# extract desired period of time from each day
idx = (9.5 <= t_15min & t_15min <= 16);
idx2 = bsxfun(@plus, find(idx), (0:numel(ymd)-1)*numel(t_15min));
P = pp(idx2(:));

%# plot interpolated data, and show extracted periods
figure, plot(tt, pp, '.-'), datetick('x'), hold on
plot([tt(idx2);nan(1,numel(ymd))], [pp(idx2);nan(1,numel(ymd))], 'r.-')
hold off, grid on, xlabel('Date/Time'), ylabel('Prices')
legend({'interpolated prices','period of 9:30 - 16:00'})

元のデータと補間されたデータを示す 2 つのプロットを次に示します。

original_data interpolated_data

于 2012-06-08T19:25:31.303 に答える
0

私はこの方法でそれを解決したかもしれないと思います:

new_timeinhr = 0:0.25:max(A(:,2));
day_hour = rem(new_timeinhr, 24);
new_timeinhr( day_hour <= 9.4 | day_hour >= 16.1 ) = [];

days=unique(data(:,1));
P=[];
for j=1:length(days);
    condition=A(:,1)==days(j);
    intprices = interp1(A(condition,2), A(condition,3), new_timeinhr);
    P=vertcat(P,intprices');
end;
于 2012-06-07T08:26:44.627 に答える