rakeeee:
次のように私はデータを持っています
//input data
df.show()
//+---+---+---+
//| x| y| z|
//+---+---+---+
//|tes| 45| 34|
//|tes| 43| 67|
//|tes| 56| 43|
//|raj| 45| 43|
//|raj| 44| 67|
//+---+---+---+
私は、これは与えられた入力の順序を変更してのように変換したいです。
//output data
df.show()
//+---+---+---+---+
//| x| y| z| n|
//+---+---+---+---+
//|tes| 45| 34| 1|
//|tes| 43| 67| 1|
//|tes| 56| 43| 1|
//|raj| 45| 43| 2|
//|raj| 44| 67| 2|
//+---+---+---+---+
BlueSheepToken:
ここでの考え方は、これらの情報「を追加」にローリング合計を行うには、その後、「?それは新しいXれる」情報を持つ新しい列を追加する方法を見つけることです、と。
// Some imports
import org.apache.spark.sql.{functions => F}
import org.apache.spark.sql.expressions.Window
// inputs
val df = Seq(("tes", 45, 34), ("tes", 43, 67), ("tes", 56, 43), ("raj", 45, 43), ("raj", 44, 67)).toDF("x", "y", "z")
// adding new information
val windowSpec = Window.orderBy(F.monotonically_increasing_id())
val dfWithNewNameInfo = df
.withColumn("n", (F.lag($"x", 1).over(windowSpec) =!= $"x").cast("bigint"))
.na.fill(1, Seq("n"))
dfWithNewNameInfo.show
/*
+---+---+---+---+
| x| y| z| n|
+---+---+---+---+
|tes| 45| 34| 1|
|tes| 43| 67| 0|
|tes| 56| 43| 0|
|raj| 45| 43| 1|
|raj| 44| 67| 0|
+---+---+---+---+
*/
// We can see the "1" in the last column indicates whenever this is a new x
// Adding these 1
val resultDf = dfWithNewNameInfo.withColumn("n", F.sum("n").over(windowSpec))
resultDf.show
/*
+---+---+---+---+
| x| y| z| n|
+---+---+---+---+
|tes| 45| 34| 1|
|tes| 43| 67| 1|
|tes| 56| 43| 1|
|raj| 45| 43| 2|
|raj| 44| 67| 2|
+---+---+---+---+
*/
この方法は、完全にメモリにロードすることができる小型のデータフレームのための所望の結果を与えます。
注意してくださいwindowSpec
ラインで順序が、これは、次のデータフレームのために失敗します:
//+---+---+---+
//| x| y| z|
//+---+---+---+
//|tes| 45| 34|
//|tes| 43| 67|
//|raj| 45| 43|
//|raj| 44| 67|
//|tes| 56| 43|
//+---+---+---+
結果を与えます:
//+---+---+---+---+
//| x| y| z| n|
//+---+---+---+---+
//|tes| 45| 34| 1|
//|tes| 43| 67| 1|
//|raj| 45| 43| 2|
//|raj| 44| 67| 2|
//|tes| 56| 43| 3|
//+---+---+---+---+
私が理由です強くrecommand順に"x"
の中でwindowSpec
。