2008-10-19 15 views
8

Ich möchte eine Funktion für alle Spalten in einer Matrix mit MATLAB anwenden. Zum Beispiel möchte ich in der Lage sein, jede Spalte einer Matrix glatt aufzurufen, anstatt die Matrix glatt als Vektor zu behandeln (was das Standardverhalten ist, wenn Sie glatt (Matrix) nennen).Was ist der beste Weg, um Spalten einer Matrix in MATLAB zu durchlaufen?

Ich bin sicher, es muss eine idiomatische Weg, dies zu tun, aber ich kann es nicht finden, also habe ich eine map_column Funktion definiert:

function result= map_column(m, func) 
    result= m; 
    for col= 1:size(m,2) 
     result(:,col)= func(m(:,col)); 
    end 
end 

, die ich mit anrufen:

smoothed= map_column(input, @(c) (smooth(c, 9))); 

Gibt es etwas falsch mit diesem Code? Wie könnte ich es verbessern?

Antwort

3

Ihre Lösung ist in Ordnung.

Beachten Sie, dass horizcat eine erhebliche Leistungseinbuße für große Matrizen erzwingt. Es macht den Code O (N^2) statt O (N). Für eine 100x10.000-Matrix benötigt Ihre Implementierung 2.6s auf meinem Computer, der horizocat 64.5s. Für eine 100x5000-Matrix benötigt die horizcat-Implementierung 15,7 s.

Wenn Sie möchten, können Sie Ihre Funktion ein wenig verallgemeinern und sie über die letzte Dimension oder sogar über beliebige Dimensionen (nicht nur Spalten) iterieren lassen.

0

Wenn dies ein häufiger Anwendungsfall für Ihre Funktion ist, wäre es vielleicht eine gute Idee, die Funktion automatisch durch die Spalten zu durchlaufen, wenn die Eingabe kein Vektor ist.

Dies löst nicht genau Ihr Problem, aber es würde die Verwendung der Funktionen vereinfachen. In diesem Fall sollte die Ausgabe auch eine Matrix sein.

Sie können die Matrix auch in eine lange Spalte transformieren, indem Sie m(:,:) = m(:) verwenden. Es hängt jedoch von Ihrer Funktion ab, ob dies sinnvoll ist.

2

Vielleicht könnten Sie die Matrix immer mit dem 'Operator transformieren und dann das Ergebnis zurücktransformieren.

smoothed = smooth(input', 9)'; 

Das funktioniert zumindest mit der fft-Funktion.

+0

Dies gilt nicht für die reibungslose Funktion arbeiten. Wenn Sie eine Matrix glätten, wird sie als ein großer Vektor behandelt. Diese Methode wäre jedoch für einige andere Funktionen geeignet. – dmnd

10

Die MATLAB "for" -Anweisung führt eine Schleife über die Spalten von dem, was geliefert wird - normalerweise ergibt dies nur eine Folge von Skalaren, da der Vektor für (wie in Ihrem Beispiel oben) ein Zeilenvektor ist. Dies bedeutet, dass Sie den obigen Code wie folgt umschreiben kann:

function result = map_column(m, func) 
    result = []; 
    for m_col = m 
     result = horzcat(result, func(m_col)); 
    end 

Wenn func keine Spaltenvektor zurück, dann können Sie so etwas wie

f = func(m_col); 
result = horzcat(result, f(:)); 

zu zwingen, sie in eine Spalte hinzuzufügen.

1

Vergessen Sie nicht, die Ergebnismatrix vorzubelegen, wenn Sie mit großen Matrizen arbeiten. Andernfalls wird Ihre CPU viele Zyklen aufwenden, um die Matrix jedes Mal neu zuzuweisen, wenn eine neue Zeile/Spalte hinzugefügt wird.

1

Eine Möglichkeit, eine implizite Schleife über die Spalten einer Matrix zu verursachen, ist cellfun. Das heißt, Sie müssen zuerst die Matrix in ein Zellenfeld konvertieren, jede Zelle enthält eine Spalte. Dann ruf cellfun an.Zum Beispiel:

A = randn (10,5);

Sehen Sie, dass ich hier die Standardabweichung für jede Spalte berechnet habe.

cellfun (@ std, mat2cell (A, Größe (A, 1), Einsen (1, Größe (A, 2))))

am = 0,78681 1,1473 0,89789 0,66635 1,3482

Of Natürlich sind viele Funktionen in MATLAB bereits so eingerichtet, dass sie in Zeilen oder Spalten eines Arrays arbeiten, wie der Benutzer angibt. Dies gilt natürlich auch für die Std., Aber dies ist ein praktischer Weg zu testen, dass cellfun erfolgreich funktioniert.

std (A, [], 1)

am = 0,78681 1,1473 0,89789 0,66635 1,3482

Verwandte Themen