2016-04-04 123 views
2

我希望有人可能知道使用spark和scala解決此問題的簡單方法。在spark/scala中給出重複值唯一標識符

我有動物的動作在以下格式(目前在火花一個數據幀)的一些網絡數據:

id start end date 
12 0  10 20091017 
12 10 20 20091201 
12 20 0  20091215 
12 0  15 20100220 
12 15 0  20100320 

的id是動物的ID,開始和結束是運動的位置(即第二行是從位置id10到位置id20的移動)。如果開始或結束爲0,表示動物已經出生或已經死亡(即,第一排動物12出生,第三排動物已經死亡)。

我遇到的問題是數據被收集,以便動物身份證在數據庫中重新使用,所以在動物死亡後,其身份證可能會重新出現。

我想要做的是對所有重新使用的動作應用一個獨特的標籤。所以,你會得到一個數據庫類似

id start end date 
12a 0  10 20091017 
12a 10 20 20091201 
12a 20 0  20091215 
12b 0  15 20100220 
12b 15 0  20100320 

我一直在嘗試一些不同的方法,但似乎無法得到任何工作。該數據庫非常大(幾千兆字節),所以需要一些相當有效的工作。

任何幫助,非常感謝。

回答

3

可直接在DataFrames工作比較好,唯一的解決辦法是使用窗口功能,但我還是不希望特別高的性能在這裏:

import org.apache.spark.sql.expressions.Window 

val df = Seq(
    (12, 0, 10, 20091017), (12, 10, 20, 20091201), 
    (12, 20, 0, 20091215), (12, 0, 15, 20100220), 
    (12, 15, 0, 20100320) 
).toDF("id", "start", "end", "date") 

val w = Window.partitionBy($"id").orderBy($"date") 
val uniqueId = struct(
    $"id", sum(when($"start" === 0, 1).otherwise(0)).over(w)) 

df.withColumn("unique_id", uniqueId).show 

// +---+-----+---+--------+---------+ 
// | id|start|end| date|unique_id| 
// +---+-----+---+--------+---------+ 
// | 12| 0| 10|20091017| [12,1]| 
// | 12| 10| 20|20091201| [12,1]| 
// | 12| 20| 0|20091215| [12,1]| 
// | 12| 0| 15|20100220| [12,2]| 
// | 12| 15| 0|20100320| [12,2]| 
// +---+-----+---+--------+---------+