2017-06-20 1 views
6

Ich habe den folgenden Code in Matlab, die ich bin nicht vertraut mit:Wie konvertiere ich Matrizen von Matlab nach Python?

function segments = segmentEnergy(data, th) 
    mag = sqrt(sum(data(:, 1:3) .^ 2, 2)); 
    mag = mag - mean(mag); 

    above = find(mag>=th*std(mag)); 
    indicator = zeros(size(mag)); 
    indicator(above) = 1; 
    plot(mag); hold on; plot(indicator*1000, 'r') 
end 

ich diese folgende Funktion in Python geschrieben:

def segment_energy(data, th): 
    mag = np.linalg.norm((data['x'], data['y'], data['z'])) 
    print "This is the mag: " + str(mag) 
    mag -= np.mean(mag) 

    above = np.where(mag >= th * np.std(mag)) 
    indicator = np.zeros(mag.shape) 
    indicator[above] = 1 
    plt.plot(mag) 
    plt.plot(indicator * 1000, 'r') 
    plt.show() 

ich einen Fehler:

line 23, in segment_energy 
indicator[above] = 1 
IndexError: too many indices for array 

data ist eine Pandas DataFrame, die aus einer CSV-Datei mit dreiachsigen Beschleunigungsmesser Daten gelesen wurde. Die Achsen der Beschleunigungsmesserdaten sind x, y und z. Die Spalten für den Datenrahmen sind timestamp, time skipped, x, y, z und label in dieser Reihenfolge.

Der Fehler liegt daran, mag im Python-Code ist ein Skalar und ich behandle es wie eine Matrix. Allerdings bin ich nicht sicher, wie sie mag in eine Matrix in der MATLAB-Funktion verwandeln.

+2

Was sind Daten? –

+0

'Daten' ist ein Datenrahmen aus einer CSV-Datei. – dirtysocks45

+0

Versuchen Sie dann mit 'mag = np.linalg.norm (data.iloc [:, 1: 3] .values ​​())' –

Antwort

3

Die Ausgabe von numpy.linalg.norm standardmäßig geben Sie einen einzelnen Skalarwert gegeben, wie Sie derzeit die Funktion aufrufen. Da die Ausgabe von mag nun ein Skalar ist, wird nicht der Rest des Codes funktionieren, wie aus den folgenden Gründen bestimmt:

  1. Performing mittlere Subtraktion mit einem einzelnen Skalare gibt Ihnen einen Wert von 0 (dh mag <- mag - np.mean(mag) --> 0) . Die above-Anweisung gibt immer ein Tupel eines einzelnen Elements zurück. Dieses Element enthält ein NumPy-Array der Länge 1 mit dem Index 0, das symbolisiert, dass das erste Element des "Arrays", das in diesem Fall ein Skalar ist, die Bedingung erfüllt. Dies ist immer erfüllt, wenn die Standardabweichung einer einzelnen Konstante auch 0 ist, indem die Standarddefinition np.std verwendet wird.

  2. Das Aufrufen von shape für einen einzelnen Skalarwert ist undefiniert und gibt Ihnen eine leere Form: (). Beachten Sie, dass, wenn Sie nicht mit numpy.mean subtrahiert wurden, würde mag.shape Ihnen tatsächlich einen Fehler geben, da es kein NumPy-Array ist. Subtrahieren mit np.mean vereinigt den Skalar zu einem NumPy-Array.

    beachten:

    In [56]: mag = 10 
    
    In [57]: type(mag) 
    Out[57]: int 
    
    In [58]: mag -= np.mean(mag) 
    
    In [59]: type(mag) 
    Out[59]: numpy.float64 
    
  3. Schließlich wird die indicator Schaffung Code ruft eine Reihe von leeren Dimensionen erzeugen und da Sie indizieren in ein Array versuchen, die keine Größe hat, wird es Ihnen einen Fehler geben.

Beachten Sie diese reproduzierbaren Fehler unter der Annahme, dass mag einen Wert berechnet wurde ... sagen wir ... 10 und th = 1:

In [60]: mag = 10 

In [61]: mag -= np.mean(mag) 

In [62]: mag.shape 
Out[62]:() 

In [63]: th = 1 

In [64]: above = np.where(mag >= th * np.std(mag)) 

In [65]: indicator = np.zeros(mag.shape) 

In [66]: indicator 
Out[66]: array(0.0) 

In [67]: mag 
Out[67]: 0.0 

In [68]: indicator[above] = 1 
--------------------------------------------------------------------------- 
IndexError        Traceback (most recent call last) 
<ipython-input-67-adf9cff7610a> in <module>() 
----> 1 indicator[above] = 1 

IndexError: too many indices for array 

Daher ist die Lösung für Sie zu überdenken, wie Sie sind diese Funktion schreiben.Der MATLAB-Code geht davon aus, dass data bereits eine 2D-Matrix ist, daher berechnen sie die Norm oder die Länge jeder Zeile unabhängig voneinander. Da wir jetzt wissen, dass die Eingabe ein Pandas DataFrame ist, können wir sehr einfach numpy Operationen darauf anwenden, genau wie in MATLAB. Angenommen, Ihre Spalten sind in Ihrem Code mit x, y und z gekennzeichnet und jede Spalte ist ein numpy Array von Werten, ändern Sie einfach die erste Zeile des Codes.

def segment_energy(data, th): 
    mag = np.sqrt(np.sum(data.loc[:, ['x','y','z']]** 2.0, axis=1)) # Change 
    mag = np.array(mag) # Convert to NumPy array 
    mag -= np.mean(mag) 

    above = np.where(mag >= th * np.std(mag)) 
    indicator = np.zeros(mag.shape) 
    indicator[above] = 1 
    plt.plot(mag) 
    plt.plot(indicator * 1000, 'r') 
    plt.show() 

Die erste Anweisung im Code ist die tatsächliche NumPy-Übersetzung des Codes in MATLAB. Wir verwenden die Methode loc, die zu den Pandas DataFrame gehört, um die drei gesuchten Spalten zu indizieren. Wir müssen auch in ein NumPy-Array konvertieren, damit der Rest der Berechnungen funktioniert.

Sie können auch numpy.linalg.norm verwenden, aber geben Sie eine Achse an, die bearbeitet werden soll. Da die Daten 2D ist, geben Sie axis=1 die reihenweise Normen Ihrer Matrix zu berechnen:

mag = np.linalg.norm(data.loc[:, ['x', 'y', 'z']], axis=1) 

Die oben wird für Sie die Daten in ein NumPy Array verschmelzen.

+0

'data' ist ein Pandas-Datenrahmen, der aus einer CSV-Datei mit dreiachsigen Beschleunigungsmesserdaten gelesen wurde. Die Achsen der Beschleunigungsmesserdaten sind "x", "y" und "z". Danke für Ihre Hilfe. Wenn Sie mehr Klärungen benötigen, zögern Sie nicht zu fragen. Die Spalten für den Datenrahmen sind "Zeitstempel", "Zeit übersprungen", "x", "y", "z" und "Label" in dieser Reihenfolge. – dirtysocks45

+1

@ dirtysocks45 Verstanden. Ich habe meine Antwort bearbeitet, um die Tatsache zu nutzen, dass du Pandas verwendest. Ich habe den Code für die Positionen der Spalten agnostisch gemacht und die Labels direkt verwendet. – rayryeng

+1

Das hat das Problem behoben. Vielen Dank. – dirtysocks45