2017-04-26 5 views
1

私は2つのテーブルを持っています.1つはReasonsと呼ばれ、9つのレコードがあり、もう1つはIDが40kレコードです。ランダムに2つのデータフレームを結合する

の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| 
+-----------------+ 

私は唯一の9レコードを持っているし、IDのデータフレームに、私は40Kを持っている理由からで、この

|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 

のような出力をしたいですレコード、私はすべてのIDにランダムに理由を割り当てたい。

答えて

2

以下の解決策は、理由の数(つまり、クラスタに合理的に合うように多くの理由を持つことができます)により頑強になります。いくつか理由がある場合(OPの質問のように)、あなたはおそらくそれらをブロードキャストしたり、udfに埋め込んで簡単にこの問題を解決できます。


一般的な考え方は、IDSのデータセットに(順次)の理由のために、次にランダムな値は0から(Nは、多くの理由で)Nのインデックスを作成し、これらを使用して2つのテーブルを結合することです2つの新しい列。

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 –