2017-08-22 1 views
1

ÜbersichtMATLAB - eine Matrix von Summen von Elementen Zurückkommend auf die gleiche Art entsprechenden

Eine n×m Matrix A und einen n×1 Vektor Date sind die Eingänge der Funktion S = sumdate(A,Date).

Die Funktion gibt einen n×m Vektor S, so daß alle Zeilen in S die Summe der Zeilen von A ab dem gleichen Zeitpunkt entsprechen.

Zum Beispiel, wenn

A = [1 2 7 3 7 3 4 1 9 
    6 4 3 0 -1 2 8 7 5]'; 
Date = [161012 161223 161223 170222 160801 170222 161012 161012 161012]'; 

Dann würde ich die zurückgegebene Matrix erwarten S ist

S = [15 9 9 6 7 6 15 15 15; 
    26 7 7 2 -1 2 26 26 26]'; 
  • Da die Elemente Date(2) und Date(3) gleich sind, haben wir

    1. S(2,1) und S(3,1) beide gleich der Summe aus A(2,1) und A(3,1)
    2. S(2,2) und S(3,2) beide gleich der Summe aus A(2,2) und A(3,2).
  • Da die Elemente Date(1), Date(7), Date(8) und Date(9) gleich sind, haben wir

    1. S(1,1), S(7,1), S(8,1), gleich S(9,1) die Summe von A(1,1), A(7,1), A(8,1), A(9,1)

    2. S(1,2), S(7,2), S(8,2), S(9,2) gleich die Summe von A(1,2), A(7,2), A(8,2), A(9,2)

Das gleiche gilt für S([4,6],1) und S([4,6],2)

Als das Element Date(5) nicht wiederholt, so S(5,1) = A(5,1) = 7 und S(5,2) = A(5,2) = -1 .


Der Code, den ich bisher

hier geschrieben haben, ist mein Versuch auf den Code für diese Aufgabe.

function S = sumdate(A,Date) 
    S = A; %Pre-assign S as a matrix in the same size of A. 
    Dlist = unique(Date); %Sort out a non-repeating list from Date 
    for J = 1 : length(Dlist) 
     loc = (Date == Dlist(J)); %Compute a logical indexing vector for locating the J-th element in Dlist 
     S(loc,:) = repmat(sum(S(loc,:)),sum(loc),1); %Replace the located rows of S by the sum of them 
    end 
end 

Getestet habe ich es auf meinem Computer A und Date mit diesen Attributen:

size(A) = [33055 400]; 
size(Date) = [33055 1]; 
length(unique(Date)) = 2645; 

Es ist mein PC Sekunden etwa 1,25 nahm die Aufgabe auszuführen.

Diese Aufgabe wird in meinem Projekt hunderttausende Male ausgeführt, daher ist mein Code zu zeitaufwändig. Ich denke, dass die Leistung gesteigert wird, wenn ich die obige Schleife eliminieren kann.

Ich habe einige eingebaute Funktionen gefunden, die spezielle Arten von Summen wie accumarray oder cumsum machen, aber ich habe immer noch keine Ideen, wie die For-Schleife zu beseitigen.

Ich würde Ihre Hilfe zu schätzen wissen.

+3

Hinweis: Sie sollten 'verwenden .'' Matrices transponieren, nicht die komplexe konjugierte Transponierte' ' ' – Wolfie

+0

Vielen Dank für Ihre Bearbeitung und Beratung. Du hast recht, ich sollte stattdessen '.'' verwenden, da ich in diesem Fall keine Konjugate benötige, in denen die Eingabe komplexe Zahlen enthält. – Leba

+0

Kein Problem, ich beendete die Bearbeitung für Sie, aber in Zukunft versuchen und verwenden 'Code Formatierung' anstelle von ** fett formatieren ** Wenn Sie Code in Ihrem Text haben, macht es die Dinge viel klarer – Wolfie

Antwort

3

Sie können dies mit accumarray tun, aber Sie müssen eine Reihe von Zeilen- und Spaltenindizes in A erstellen, um es zu tun. Hier ist, wie:

[~, ~, index] = unique(Date); % Get indices of unique dates 
subs = [repmat(index, size(A, 2), 1) ...   % repmat to create row subscript 
     repelem((1:size(A, 2)).', size(A, 1))]; % repelem to create column subscript 
S = accumarray(subs, A(:)); % Reshape A into column vector for accumarray 
S = S(index, :);    % Use index to expand S to original size of A 

S = 

    15 26 
    9  7 
    9  7 
    6  2 
    7 -1 
    6  2 
    15 26 
    15 26 
    15 26 

Hinweis # 1: Dieser mehr Speicher als Ihre for-Schleife Lösung verwenden (subs wird die doppelte Anzahl von Elemente als A), aber Ihnen kann eine signifikante Geschwindigkeitserhöhung geben.

Hinweis # 2: Wenn Sie eine ältere MATLAB-Version als R2015a verwenden, haben Sie keine repelem. Stattdessen können Sie diese Zeile mit kron (oder eine der anderen Lösungen here) ersetzen:

kron((1:size(A, 2)).', ones(size(A, 1), 1)) 
+1

Wenn Sie nicht ' t haben 'repelem' siehe [hier] (https://stackoverflow.com/questions/1975772/repeat-copies-of-array-elements-run-length-decoding-in-matlab) –

+0

@ Jon: Danke, fügte ich hinzu eine Notiz dafür. – gnovice

+0

Meine Version ist 2016a und ich habe genug RAM dafür, also ist die Lösung absolut in Ordnung für mich. Ihre Lösung ist einfach und effizient. Vielen Dank. – Leba

Verwandte Themen