2016-05-14 6 views
1

Ich muss die Spalten eines Deedle Datenrahmens basierend auf dem Wert der letzten Zeile sortieren. So würde die erste Spalte den größten Wert haben und die letzte Spalte würde den kleinsten Wert in der letzten Zeile haben. Deedles Frame hat den größten Teil seiner Funktionalität in Reihen.Sortieren Deedle Frame nach Spalten basierend auf dem Wert der letzten Zeile

Hier einige Beispielcode-Daten zu erzeugen, wo Element2 mit einem Wert größer als element1 enden wird:

#load @"..\..\FSLAB\packages\FsLab\FsLab.fsx" 
open System 
open System.Drawing 
open System.Windows.Forms 
open Deedle 
open FSharp.Charting 
open FSharp.Charting.ChartTypes 

let rnd = new System.Random() 
let dateRange = [for i in 9..-1..0 -> DateTime.Today.AddDays(float -i)] 
let makeData x = [for i in 0..x-2 -> rnd.NextDouble()-0.5] |> List.scan (+) 0. 
let series = makeData 10 |> List.zip <| (makeData 10 |> List.map (fun x -> x + 1.)) 
let df = series |> Frame.ofRecords 
df?DateIndex <- dateRange |> Series.ofValues 
let df = df.IndexRows<DateTime>("DateIndex") 

In diesem Fall wird die letzte Zeile des Rahmens wird wie folgt aussehen, die größere der Werte mit in der zweiten Spalte:
2016/05/14 0:00:00 -> 0.143158562780897 0.918480403450541

Aber ich möchte, dass es in dieser Reihenfolge haben:
2016/05/14 0:00:00 -> 0.918480403450541 0.143158562780897

Ich habe eine Antwort gepostet, würde aber gerne sehen, ob es andere Ansätze gibt, da ich mit Deedle noch nicht so vertraut bin.

Antwort

1

Frame.sortRowsWith braucht eine Sortierfunktion:

let reverser (a:float) (b:float) = 
    if a > b then 
     -1 
    else if a < b then 
     1 
    else 
     0 

let df1 = df |> Frame.transpose 
let coldIdx = df1.ColumnKeys |> Seq.max 
Frame.sortRowsWith coldIdx reverser df1 |> Frame.transpose 

So transponiert er den Datenrahmen, erhält dann den Index der letzten Zeile (Spalte in diesem Fall) und sortiert die Spalten vom größten bis zum kleinsten, schließlich die Umsetzung zurück. Dies ist praktisch für das Charting, da auf diese Weise die Legenden des Diagramms mit der Reihe im Diagramm übereinstimmen.

+0

@FoggyFinder thx für diesen Vorschlag: 'Let reverser (a: 'T) (b:' T wenn 'T:> System.IComparable) = b.CompareTo (a)' – s952163

Verwandte Themen