2016-08-03 9 views
1

Ich habe in einem Pyspark-Datenframe eine Spalte mit den Werten 1, -1 und 0, die die Ereignisse "Start", "Shutdown" und "Sonstiges" einer Engine darstellt. Ich möchte eine Spalte mit dem Zustand des Motors bauen, mit 1, wenn der Motor eingeschaltet ist und 0, wenn es ausgeschaltet ist, so etwas wie:Entwerfen einer gesättigten Summe mit Fensterfunktionen

+---+-----+-----+ 
|seq|event|state| 
+---+-----+-----+ 
| 1 | 1 | 1 | 
| 2 | 0 | 1 | 
| 3 | -1 | 0 | 
| 4 | 0 | 0 | 
| 5 | 0 | 0 | 
| 6 | 1 | 1 | 
| 7 | -1 | 0 | 
+---+-----+-----+ 

Wenn 1s und -1s immer abgewechselt werden, kann dies leicht getan werden mit einer Fensterfunktion wie

sum('event').over(Window.orderBy('seq')) 

Es kann passieren, aber, dass ich einige falsche 1s oder -1s, die ich ignoriert werden sollen, wenn ich bereits bin im Zustand 1 bzw. 0. Ich mag daher in der Lage sein, etwas zu tun wie:

+---+-----+-----+ 
|seq|event|state| 
+---+-----+-----+ 
| 1 | 1 | 1 | 
| 2 | 0 | 1 | 
| 3 | 1 | 1 | 
| 4 | -1 | 0 | 
| 5 | 0 | 0 | 
| 6 | -1 | 0 | 
| 7 | 1 | 1 | 
+---+-----+-----+ 

, dass eine „gesättigt“ Summenfunktion erfordern würde, die nie über 1 oder unter 0 geht, oder einen anderen Ansatz, den ich nicht in der Lage bin im Moment vorstellen .

Hat jemand irgendwelche Ideen?

Antwort

0

Sie können das gewünschte Ergebnis erzielen, indem Sie die letzte Funktion verwenden, um die letzte Statusänderung auszufüllen.

from pyspark.sql import functions as F 
from pyspark.sql.window import Window 

df = (spark.createDataFrame([ 
     (1, 1), 
     (2, 0), 
     (3, -1), 
     (4, 0) 
    ], ["seq", "event"])) 

w = Window.orderBy('seq') 

#replace zeros with nulls so they can be ignored easily. 
df = df.withColumn('helperCol',F.when(df.event != 0,df.event)) 

#fill statechanges forward in a new column. 
df = df.withColumn('state',F.last(df.helperCol,ignorenulls=True).over(w)) 

#replace -1 values with 0 
df = df.replace(-1,0,['state']) 

df.show() 

Dies erzeugt:

+---+-----+---------+-----+ 
|seq|event|helperCol|state| 
+---+-----+---------+-----+ 
| 1| 1|  1| 1| 
| 2| 0|  null| 1| 
| 3| -1|  -1| 0| 
| 4| 0|  null| 0| 
+---+-----+---------+-----+ 

helperCol braucht nicht auf den Datenrahmen hinzugefügt werden, ich habe enthalten sie nur den Prozess besser lesbar zu machen.

Verwandte Themen