質問
いくつかのコードは機能しますが、少しボトルネックになっており、高速化する方法を見つけるのに苦労しています。ループ内にあり、ベクトル化する方法がわかりません。
時系列データを表す 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の中央の上のファイル交換にコンソリを探す