2017-04-26 76 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 –