2016-07-14 16 views
1

Ich habe einen Datensatz in einem Maple-Datenrahmen gespeichert, den ich nach Werten in einer bestimmten Spalte sortieren möchte. Mein Beispiel ist größer, aber die Daten sind so, dass ich zwei Datenspalten habe, eine mit einigen numerischen Werten und die andere mit Strings. So zum Beispiel, sagen, wenn ich einen Datenrahmen aufgebaut habe, wie:Sortieren eines Maple-Datenrahmens nach dem Inhalt einer Spalte

Mydata := DataFrame(<<2,1,3,0>|<"Red","Blue","Green","Orange">>, columns = [Value,Color]); 

ich so etwas wie der Befehl sort möchte den gleichen Datenrahmen mit den Zahlen in der Spalte Wert der Lage sein, in auf- oder absteigender Reihenfolge sortierten zurückzukehren , aber der Befehl sort scheint keine Datenrahmen zu unterstützen. Irgendwelche Ideen, wie ich das sortieren kann?

Antwort

3

Sie haben recht, dass der sort Befehl derzeit DataFrames nicht unterstützt (aber es sollte!). Ich habe dies um converting die DataFrame-Spalte (eine DataSeries) zu einem Vektor, sortieren den Vektor mit output = permutation Option und dann Indexierung der DataFrame durch das Ergebnis. Mit Ihrem Beispiel:

Mydata := DataFrame(<<2,1,3,0>|<"Red","Blue","Green","Orange">>, columns = [Value,Color]); 
sort(convert(Mydata[Value], Vector), output = permutation); 

Welche zurück:

[4, 2, 1, 3] 

dieses Ergebnis die ursprüngliche Datenrahmen Indizierung kehrt dann die sortierte Datenrahmen in ansteigender Reihenfolge der Spalte Wert:

Mydata[ sort(convert(Mydata[Value], Vector), output = permutation), .. ]; 
Mydata[ [4, 2, 1, 3], .. ]; 

kehrt:

 [  Value  Color ] 
     [      ] 
     [4  0  "Orange"] 
     [      ] 
     [2  1  "Blue" ] 
     [      ] 
     [1  2  "Red" ] 
     [      ] 
     [3  3  "Green" ] 

Das heißt, ich musste DataFrames einige Male sortieren, also habe ich auch eine Prozedur erstellt, die für die meisten meiner Datensätze zu funktionieren scheint. Diese Prozedur verwendet einen ähnlichen Ansatz wie der Befehl sort, benötigt jedoch keine Datenkonvertierungen, da sie auf dem Maple DataFrame-Objekt selbst ausgeführt wird. Dazu muss ich kernelopts(opaquemodules = false) einstellen, um direkt mit dem internen DataFrame-Datenobjekt zu arbeiten (Sie könnten auch eine Reihe von Konvertierungen zu intermediären Matrizen und Vektoren vornehmen, aber diese Vorgehensweise begrenzt die Anzahl der erstellten internen Duplikate):

DSort := proc(self::{DataFrame,DataSeries}, {ByColumn := NULL}) 
    local i, opacity, orderindex; 
    opacity := kernelopts('opaquemodules' = false): 
    if type(self, ':-DataFrame') and ByColumn <> NULL then 
     orderindex := sort(self[ByColumn]:-data, ':-output' = ':-permutation', _rest); 
    elif type(self, ':-DataSeries') and ByColumn = NULL then 
     orderindex := sort(self:-data, ':-output' = ':-permutation', _rest); 
    else 
     return self; 
    end if; 
    kernelopts(opaquemodules = opacity): #Set opaquemodules back to original setting 
    if type(self, ':-DataFrame') then 
     return DataFrame(self[ orderindex, .. ]); 
    else 
     return DataSeries(self[ orderindex ]); 
    end if; 
end proc: 

zum Beispiel:

DSort(Mydata, ByColumn=Value); 

kehrt:

 [  Value  Color ] 
     [      ] 
     [4  0  "Orange"] 
     [      ] 
     [2  1  "Blue" ] 
     [      ] 
     [1  2  "Red" ] 
     [      ] 
     [3  3  "Green" ] 

Dies auch auf Strings arbeitet, so DSort(Mydata, ByColumn=Color); sollte funktionieren.

 [  Value  Color ] 
     [      ] 
     [2  1  "Blue" ] 
     [      ] 
     [3  3  "Green" ] 
     [      ] 
     [4  0  "Orange"] 
     [      ] 
     [1  2  "Red" ] 

In diesem Verfahren gehe ich zusätzliche Argumente an den sort Befehl, was bedeutet, dass Sie auch in auf- oder absteigenden Optionen hinzufügen können, so könnte man DSort(Mydata, ByColumn=Value, `>`); tun, um den Datenrahmen zurück in absteigender Reihenfolge ‚Value‘ bestellen (dies scheint jedoch nicht gut mit Streichern zu spielen).