2016-07-20 7 views
4

Ich habe einen Datenrahmen mit 3 für diese Frage relevanten Werten, :ID, :Position, :Probability. Jede Zeile ist eindeutig, aber mehrere Zeilen können dieselbe ID haben. Was ich tun möchte, ist alle Zeilen für einen bestimmten Wert von Position, die eine ID mit jeder Zeile, die eine Probability höher als ein Wert in einer anderen Position hat teilen.Effizienter Satzschnittpunkt zum Abrufen von Zeilen im Datenrahmen

Zum Beispiel sagen, dass ich den folgenden Datenrahmen (df) habe:

1020692×8 DataFrames.DataFrame 
│ Row  │ ID │ Position  │ Probability │ 
├─────────┼─────┼───────────────┼─────────────┤ 
│ 1  │ 425 │ "first"  │ 0.02  │ 
│ 2  │ 425 │ "last"  │ 0.03  │ 
│ 3  │ 425 │ "penultimate" │ 0.02  │ 
│ 4  │ 425 │ "other"  │ 0.04  │ 
│ 5  │ 421 │ "first"  │ 0.44  │ 
│ 6  │ 421 │ "last"  │ 0.85  │ 
│ 7  │ 421 │ "second"  │ 0.59  │ 
│ 8  │ 421 │ "other"  │ 1.0   │ 
⋮ 

Wenn ich einen Schwellenwert von 0.8 gesetzt, ich will mit allen Zeilen landen, wo :Position == "first" wenn die :ID:Position == "last" && :Probability > 0.8 hat. Mit anderen Worten, ich würde Zeile 5 wollen, da Zeile 6 eine :Probability > 0.8 hat, aber nicht Zeile 1, da Zeile 2 nicht.

Die Zeile zum Überprüfen des Schwellenwerts folgt nicht immer der Zeile, die ich behalten möchte. Nicht alle Zeilen, bei denen :Position == "first" eine "last" Zeile zu überprüfen hat, aber es wird höchstens eins geben.

Die Art und Weise habe ich versucht, dieses Problem zu lösen war ein Vektor aller ID s in last Position mit Probability > 0.8 zu machen, und dann versucht, die Datenrahmen mit in() der Teilmenge. So ...

firsts = df[df[:Position] .== "first", :] 
lasts = df[df[:Position] .== "last", :] 
meetsthreshold = lasts[lasts[:Probability] .> 0.8, :ID] 

final = firsts[[in(i, meetsthreshold) for i in firsts[:ID]], :] 

Getestet habe ich diese mit einem super kurzen Vektor von ID s und es funktioniert, aber es hinkt super hart auf meinen eigentlichen Daten (wo length(meetsthreshold) ist> 100k). Ich denke, was ich will, ist im Grunde eine Schnittmenge, und wenn ich das mit der ID s (zB intersect(Set(firsts[:ID]), Set(meetsthreshold))) mache, ist es im Grunde sofort. Gibt es eine Möglichkeit, die gesetzte Kreuzung mit einem Datenrahmen zu machen, damit ich die Reihen tatsächlich bekommen kann?

+0

Mein Tipp wäre versuchen: 'von (g-> Maximum (g [: Wahrscheinlichkeit])> 0.9? G [g [: Position]. ==" erste ",:]: DataFrame(), df ,: ID) '. Aber es ist unordentlich. Schau dir 'by' und' groupby' an. –

+0

Interessante Idee - Ich habe 'by' für ein paar Dinge benutzt, aber ich verstehe die Syntax von dem, was du geschrieben hast, nicht ganz ... Das ist eine abgespeckte if-else-Anweisung, oder? – kevbonham

+0

Ja. Es ist eine Abkürzung für eine "if" -Anweisung. Hast du es versucht? –

Antwort

2

ich irgendwie wie ein Idiot fühlen - die Lösung verwenden nur einen Satz anstelle eines Vektors in suchen, zB:

firsts = df[df[:Position] .== "first", :] 
lasts = df[df[:Position] .== "last", :] 
meetsthreshold = Set(lasts[lasts[:Probability] .> 0.8, :ID]) 

final = firsts[Vector{Bool}([in(i, meetsthreshold) for i in firsts[:ID]]), :] 

Ran in ~ 1 Sekunde..

+0

Da es seit 6 Monaten keine weiteren Antworten mehr gibt, ging ich weiter und markierte dies beantwortet. – kevbonham