2017-03-10 6 views
1

MATLABs accumarray ist in vielen Anwendungen unglaublich leistungsfähig. Mein Problem ist, dass meine accumarray Funktion, die auf meine Eingänge angewendet wird, drei Ausgänge hat, und accumarray kann nur skalare Ausgänge verarbeiten. Zum Beispiel würde ich so etwas tun:Verwendung von Akkumulator zur Ausgabe einer Matrix

subs = [1;2;4;2;4;5]; 
vals = [1;1;1;2;5;1]; 
accumarray(subs, vals, [], @(x)[min(x),mean(x),max(x)],0) 

und haben accumarray Rückkehr:

1.0000 1.0000   0 1.0000 1.0000 
1.0000 1.5000   0 3.0000 1.0000 
1.0000 2.0000   0 5.0000 1.0000 

Ich glaube, ich nur accumarray dreimal laufen konnte, aber meine Funktion ist langsam, und Laufen accumarray einmal wäre viel schneller als drei Mal. Bin ich hier nur abgespritzt?

+0

Alternativ können Sie [grpstats] (https://www.mathworks.com/help/stats/repeatedmeasuresmodel.grpstats.html) von Statistics toollbox verwenden oder Sie können [regionprops] (https: //www.mathworks. com/help/images/ref/regionprops.html) aus der Bildbearbeitungs-Toolbox, wenn Sie eine Lizenz haben. – rahnema1

+0

@ rahnema1, min/mean/max war nur ein konkretes Beispiel, um mein Problem zu demonstrieren. Meine eigentliche Funktion für accumarray ist ziemlich verschieden von min/mean/max, also hilft mir grpstats nicht. Ich benutze regionprops täglich, aber ich habe keine Ahnung, was Sie beschreiben. – John

+0

Sie können regionprops verwenden, um statistische Eigenschaften von Regionen zu finden. Verwendung: 'stats = regionprops (Subs, Vals, 'MaxIntensity', 'MeanIntensity', 'MinIntensity')'. Wie Sie siad, dass Ihre eigentliche Funktion für accumarray ist ziemlich anders als min/Mittelwert/max so Regionsprops hilft auch nicht. – rahnema1

Antwort

3

Sie können schummeln lassen die anonyme Funktion ein Zellenfeld anstelle eines einzelnen Werts ausgeben. Auf diese Weise erhalten Sie accumarray eine Matrix von Zellen. Sie können dann alle Matrizen zu einer einzigen Matrix verketten, wenn Sie fertig sind. Beachten Sie, dass Ihre vorgeschlagene anonyme Funktion die min, max und mean als Zeilenvektor hat, aber Ihr erwartetes Ergebnis ist eine Spalte Vektor. Deshalb habe ich das in Ihrer anonymen Funktion umgesetzt.

Die Frage, die wir berücksichtigen müssen, ist der Füllwert. Der von Ihnen angegebene Füllwert muss ein Skalar sein. Sie können also schummeln, indem Sie dies auslassen, aber dann enthält Ihre Ausgabe nun leere Matrizen in der Zelle anstelle der Zeile des Ergebnisses, die mit 0 gefüllt ist. Ein Weg, um dies zu finden, besteht darin, alle Zellen zu finden, die leer sind eine Reihe von Nullen, dann fügen Sie alles zusammen, wenn Sie fertig sind. Um herauszufinden, welche Zeilen der accumarray Ausgabe leer sind, können Sie cellfun kombiniert mit isempty verwenden, damit wir sehen können, welche Elemente im Ergebnis leer sind. Eine ordentliche Art und Weise, dies zu tun wäre, um erster vorbelegt eine Matrix aus zeros dann nur die Zeilen füllen, die zu den nicht-leeren Stellen in der Ausgabe von accumarray entsprechen es zu beenden:

subs = [1;2;4;2;4;5]; 
vals = [1;1;1;2;5;1]; 
out = accumarray(subs, vals, [], @(x){[min(x),mean(x),max(x)].'}); 
ind_empty = cellfun('isempty', out); 
out_final = zeros(3, numel(out)); 
out_final(:, ~ind_empty) = cat(2, out{:}); 

Beachten die Verwendung von cat, die Matrizen in einer bestimmten Dimension miteinander verkettet. Doing out{:} produziert, was als comma-separated list bekannt ist, so ist es äquivalent zu jeder Spalte der accumarray Ausgabe und setzen sie als einzelne Argumente in cat, so dass wir schließlich alle Spalten zusammen in einer einzigen Matrix, aber ich schneide in die Ausgabe so ein, dass wir nur die Orte bevölkern, die nicht leer waren.

Mit Ihren Testeingaben, ich passe, was man bekommt:

>> out_final 

out_final = 

    1.0000 1.0000   0 1.0000 1.0000 
    1.0000 1.5000   0 3.0000 1.0000 
    1.0000 2.0000   0 5.0000 1.0000 

Allerdings, wenn ich ehrlich sein kann - wenn Sie sicher wissen, dass Sie nur gehen zu sind drei Werte haben in accumarray, kann es schneller sein, es einfach dreimal aufzurufen, dann verketten Sie alles, wenn Sie fertig sind. Ich würde argumentieren, dass es lesbarer ist und es sehr deutlich macht, was Sie tun. Wenn Sie so vorgehen, wie Sie es mit dem obigen Zellenfeld getan haben, müssen Sie wirklich wissen, wie MATLAB funktioniert.

Verwandte Themen