2017-04-26 66 views
1

我有兩個表,一個叫做Reasons,有9個記錄,另一個包含40k個記錄的ID。隨機連接兩個數據幀

編號:

+------+------+ 
|pc_pid|pc_aid| 
+------+------+ 
| 4569| 1101| 
| 63961| 1101| 
|140677| 4364| 
|127113|  7| 
| 96097| 480| 
| 8309| 3129| 
| 45218| 89| 
|147036| 3289| 
| 88493| 3669| 
| 29973| 3129| 
|127444| 3129| 
| 36095| 89| 
|131001| 1634| 
|104731| 781| 
| 79219| 244| 
+-------------+ 

原因:

+-----------------+ 
|   reasons| 
+-----------------+ 
|  follow up| 
|   skin chk| 
|  annual meet| 
|review lab result| 
|  REF BY DR| 
|  sick visit| 
|  body pain| 
|    test| 
|   other| 
+-----------------+ 

我想這樣

|pc_pid|pc_aid| reason 
+------+------+------------------- 
| 4569| 1101| body pain 
| 63961| 1101| review lab result 
|140677| 4364| body pain 
|127113|  7| sick visit 
| 96097| 480| test 
| 8309| 3129| other 
| 45218| 89| follow up 
|147036| 3289| annual meet 
| 88493| 3669| review lab result 
| 29973| 3129| REF BY DR 
|127444| 3129| skin chk 
| 36095| 89| other 

在我只有9條,並在ID數據幀我有40K的原因輸出記錄,我想將理由隨機分配給每個ID。

回答

2

以下解決方案試圖使原因的數量更穩健(即,您可以擁有儘可能多的理由,因爲您可以合理地適應羣集)。如果你只有幾個原因(如OP所要求的),那麼你可能會廣播它們或將它們嵌入到一個udf中,並輕鬆解決這個問題。


總的想法是對ID的數據集創建一個索引(順序)的理由,然後從0隨機值N(其中N是數量的原因),然後加入用這些兩個表兩個新的專欄。這裏是你如何能做到這一點:

case class Reasons(s: String) 
defined class Reasons 

case class Data(id: Long) 
defined class Data 

數據將持有的ID(簡化了OP的版本)和原因都會舉行一些簡單的原因。

val d1 = spark.createDataFrame(Data(1) :: Data(2) :: Data(10) :: Nil) 
d1: org.apache.spark.sql.DataFrame = [id: bigint] 

d1.show() 

+---+ 
| id| 
+---+ 
| 1| 
| 2| 
| 10| 
+---+ 

val d2 = spark.createDataFrame(Reasons("a") :: Reasons("b") :: Reasons("c") :: Nil) 

+---+ 
| s| 
+---+ 
| a| 
| b| 
| c| 
+---+ 

我們稍後需要一些理由,所以我們先計算一下。

val numerOfReasons = d2.count() 

val d2Indexed = spark.createDataFrame(d2.rdd.map(_.getString(0)).zipWithIndex) 

d2Indexed.show() 
+---+---+ 
| _1| _2| 
+---+---+ 
| a| 0| 
| b| 1| 
| c| 2| 
+---+---+ 

val d1WithRand = d1.select($"id", (rand * numerOfReasons).cast("int").as("rnd")) 

最後一步是加入新列並刪除它們。

val res = d1WithRand.join(d2Indexed, d1WithRand("rnd") === d2Indexed("_2")).drop("_2").drop("rnd") 

res.show() 

+---+---+ 
| id| _1| 
+---+---+ 
| 2| a| 
| 10| b| 
| 1| c| 
+---+---+ 
+0

謝謝@marios –