2017-09-11 11 views
0

작은 데이터 프레임을 다른 큰 데이터 프레임의 UDF 내부에서 사용될 브로드 캐스트 조회 테이블로 변환하고 싶습니다. 이 작은 dataframe (myLookupDf는) 다음과 무언가 같이 보일 수 있습니다 :Spark Dataframe에서 2D 룩업 테이블을 작성하십시오.

+---+---+---+---+ 
| x | 90|100|101| 
+---+---+---+---+ 
| 90| 1| 0| 0| 
|100| 0| 1| 1| 
|101| 0| 1| 1| 
+---+---+---+---+ 

내가 첫 번째 키와 첫 번째 열을 사용하려면 1 개, 두 번째 키와 첫 번째 행을 말한다. x1과 x2는 같은 요소를 가지고 있습니다. 이상적으로, 룩업 테이블 (myLookupMap)는 스칼라지도 할 (또는 유사)와 같이 작동합니다 :의 배열입니다

val myLookupMap = myLookupDf.collect().map(r => Map(myLookupDf.columns.zip(r.toSeq):_*)) 
myLookupMap: Array[scala.collection.Map[String,Any]] = Array(Map(x -> 90, 90 -> 1, 100 -> 0, 101 -> 0), Map(x -> 100, 90 -> 0, 100 -> 1, 101 -> 1), Map(x -> 101, 90 -> 0, 100 -> 1, 101 -> 1)) 

을 :

myLookupMap(90)(90) returns 1 
myLookupMap(90)(101) returns 0 
myLookupMap(100)(90) returns 0 
myLookupMap(101)(100) return 1 
etc. 

는 지금까지 내가 가지고 관리 정확히 무엇이 필요한지도가 아니라지도. 어떤 제안이라도 대단히 감사합니다.

+0

왜 당신은지도에 dataframe를 변환하는? 그리고 어떻게 방송 된 df를 다른 df에 사용하고 싶습니까? –

+0

룩업 테이블은 UDF에서 사용되므로 데이터 프레임 일 수 없습니다. 이 접근법은 두 개의 데이터 프레임에 대한 데카르트 조인을 피하기 위해 사용됩니다. – Jonathan

+0

나는 당신의 설명에서 이해 한 것에 따라 아래에 대답했다. 나는 대답이 도움이되기를 바란다. –

답변

0

collect() 항상 Array에 해당하는 rdd을 만듭니다. arrays을 수집하는 방법을 찾으려면 maps으로 찾아야합니다.

감안할 때 당신이 필요 그래서 당신은

scala>  val header = myLookupDf.schema.fieldNames.tail 
header: Array[String] = Array(90, 100, 101) 

이하 나는대로 Map를 얻을 수 있도록 map 기능을 수정하고 같은 작업을 수행 할 수 있습니다 x 이외의 헤더 이름은 dataframe

scala> myLookupDf.show(false) 
+---+---+---+---+ 
|x |90 |100|101| 
+---+---+---+---+ 
|90 |1 |0 |0 | 
|100|0 |1 |1 | 
|101|0 |1 |1 | 
+---+---+---+---+ 

로 결과는

scala>  val myLookupMap = myLookupDf.rdd.map(r => { 
    |  val row = r.toSeq 
    |  (row.head, Map(header.zip(row.tail):_*)) 
    |  }).collectAsMap() 
myLookupMap: scala.collection.Map[Any,scala.collection.immutable.Map[String,Any]] = Map(101 -> Map(90 -> 0, 100 -> 1, 101 -> 1), 100 -> Map(90 -> 0, 100 -> 1, 101 -> 1), 90 -> Map(90 -> 1, 100 -> 0, 101 -> 0)) 

원하는 결과를 얻을 수 있어야합니다. 이제

scala> myLookupMap(90)(90.toString) 
res1: Any = 1 

scala> myLookupMap(90)(101.toString) 
res2: Any = 0 

scala> myLookupMap(100)(90.toString) 
res3: Any = 0 

scala> myLookupMap(101)(100.toString) 
res4: Any = 1 

당신이 전달할 수 myLookupMap 당신의 udf 기능에

+0

나의 기쁨 @Jonathan :) 수용에 대한 감사 :) 당신은 자격이 될 때도 역시 upvote 할 수있다. :) –