Frage

Ich habe einige Code bekam das funktioniert, ist aber ein bisschen ein Engpass, und ich bin fest versuchen, herauszufinden, wie es zu beschleunigen. Es ist in einer Schleife, und ich kann nicht verstehen, wie es vektorisieren.

Ich habe einen 2D-Array bekommt, vals, die Zeitreihendaten darstellt. Zeilen sind Termine, Spalten Serien sind. Ich versuche, die Daten, die von Monat Eimern verschiedene Operationen auf sie (Summe, Mittelwert, etc.) durchzuführen. Hier ist mein aktueller Code:

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);

Das nächste Zeile ist der Engpass, weil ich es so oft nennen. (Looping)

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

Irgendwelche Ideen? Vielen Dank im Voraus.

War es hilfreich?

Lösung

Das ist ein schwieriges Problem vektorisieren. Ich kann einen Weg vorschlagen, es zu tun mit CELLFUN , aber ich kann nicht garantieren, dass es für Ihr Problem sein wird schneller (Sie es sich auf den spezifischen Daten zu Zeit haben Sets Sie verwenden). Wie in Frage dieses andere SO , Vektorisierung nicht immer Arbeit schneller als for-Schleifen. Es kann sehr problemspezifisch sein, das die beste Option ist. Mit diesem wichtigen Hinweis, werde ich zwei Lösungen vorschlagen, die Sie ausprobieren: a. CELLFUN Version und eine Änderung Ihrer for-Schleife Version, die schneller laufen kann

CELLFUN LÖSUNG:

[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);

Der Aufruf von MAT2CELL Gruppen der Reihen von vals , die den gleichen Starttermin zusammen in Zellen eines Zellenfeldes valCell . Die Variable newVals wird ein Zellenfeld mit einer Länge von Numel (uniqueStarts) sein, wobei jede Zelle das Ergebnis der Durchführung nansum auf der entsprechenden Zelle enthalten von valCell .

FOR-LOOP LÖSUNG:

[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

Andere Tipps

Wenn alles, was Sie tun müssen, ist die Summe bilden oder bedeuten, auf Zeilen einer Matrix, wobei die Zeilen summiert werden in Abhängigkeit von anderen Variablen (Datum), dann meine Consolidator-Funktion verwenden. Es ist so konzipiert, genau diesen Vorgang zu tun, Daten basierend auf den Werten einer Indikators Serie zu reduzieren. (Eigentlich Consolidator kann auch n-d-Daten arbeiten, und mit einer Toleranz, aber alles, was Sie tun müssen, ist es, den Monat und das Jahr Informationen weitergeben.)

finden Konsolidierer auf dem Austausch von Dateien auf MATLAB Central

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top