質問

いくつかのコードは機能しますが、少しボトルネックになっており、高速化する方法を見つけるのに苦労しています。ループ内にあり、ベクトル化する方法がわかりません。

時系列データを表す 2D 配列 vals を持っています。行は日付、列は異なる系列です。データを月ごとにバケット化して、さまざまな操作(合計、平均など)を実行しようとしています。私の現在のコードは次のとおりです。

allDts; %Dates/times for vals.  Size is [size(vals, 1), 1]
vals;
[Y M] = datevec(allDts);
fomDates = unique(datenum(Y, M, 1)); %first of the month dates

[Y M] = datevec(fomDates);
nextFomDates = datenum(Y, M, DateUtil.monthLength(Y, M)+1);

newVals = nan(length(fomDates), size(vals, 2)); %preallocate for speed

for k = 1:length(fomDates);

何度も呼び出すので、この次の行がボトルネックになります。(ループ)

    idx = (allDts >= fomDates(k)) & (allDts < nextFomDates(k));
    bucketed = vals(idx, :);
    newVals(k, :) = nansum(bucketed);
end %for

何か案は?前もって感謝します。

役に立ちましたか?

解決

それをベクトル化するのは難しい問題です。を使用してそれを行う方法を提案できます セルファン, しかし、あなたの問題に対してそれがより速くなるとは保証できません(使用している特定のデータセットで自分で時間を計る必要があります)。で議論したように、 この他のSOの質問, 、ベクトル化はそうではありません いつも for ループよりも高速に動作します。問題に非常に特化したものになる可能性がありますが、これが最良の選択肢です。この免責事項を踏まえて、試してほしい 2 つの解決策を提案します。CELLFUN バージョンと、より高速に実行できる for ループ バージョンの修正。

セルファンソリューション:

[Y,M] = datevec(allDts);
monthStart = datenum(Y,M,1);  % Start date of each month
[monthStart,sortIndex] = sort(monthStart);  % Sort the start dates
[uniqueStarts,uniqueIndex] = unique(monthStart);  % Get unique start dates

valCell = mat2cell(vals(sortIndex,:),diff([0 uniqueIndex]));
newVals = cellfun(@nansum,valCell,'UniformOutput',false);

への呼び出し MAT2セル の行をグループ化します ヴァルス 同じ開始日を持つものを cell 配列のセルにまとめます ヴァルセル. 。変数 新しいヴァルス 長さのセル配列になります numel(uniqueStarts), 、各セルには実行結果が含まれます。 ナンスム の対応するセル上で ヴァルセル.

FORループソリューション:

[Y,M] = datevec(allDts);
monthStart = datenum(Y,M,1);  % Start date of each month
[monthStart,sortIndex] = sort(monthStart);  % Sort the start dates
[uniqueStarts,uniqueIndex] = unique(monthStart);  % Get unique start dates

vals = vals(sortIndex,:);  % Sort the values according to start date
nMonths = numel(uniqueStarts);
uniqueIndex = [0 uniqueIndex];
newVals = nan(nMonths,size(vals,2));  % Preallocate
for iMonth = 1:nMonths,
  index = (uniqueIndex(iMonth)+1):uniqueIndex(iMonth+1);
  newVals(iMonth,:) = nansum(vals(index,:));
end

他のヒント

あなたがする必要があるすべては、その後の私のコンソリ機能を使用する合計を形成するか、行が別の変数(日)に応じて、加算され、マトリックスの行に意味ある場合。インジケータシリーズの値に基づいてデータを削減する、まさにこの操作を行うように設計されています。 (実際には、コンソリものn次元のデータであり、許容範囲で動作することができますが、あなたがする必要があるすべては、月と年の情報を渡している。)

Matlabの中央の上のファイル交換にコンソリを探す

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top