2017-12-27 290 views
0

有什麼方法可以將數據幀行轉置爲列。 我有以下結構作爲輸入:如何將行轉換爲火花數據幀中的列,scala

val inputDF = Seq(("pid1","enc1", "bat"),("pid1","enc2", ""),("pid1","enc3", ""),("pid3","enc1", "cat"),("pid3","enc2", "")).toDF("MemberID", "EncounterID", "entry") 

inputDF.show: 

+--------+-----------+-----+ 
|MemberID|EncounterID|entry| 
+--------+-----------+-----+ 
| pid1|  enc1| bat| 
| pid1|  enc2|  | 
| pid1|  enc3|  | 
| pid3|  enc1| cat| 
| pid3|  enc2|  | 
+--------+-----------+-----+ 

expected result: 

+--------+----------+----------+----------+-----+ 
|MemberID|Encounter1|Encounter2|Encounter3|entry| 
+--------+----------+----------+----------+-----+ 
| pid1|  enc1|  enc2|  enc3| bat| 
| pid3|  enc1|  enc2|  null| cat| 
+--------+----------+----------+----------+-----+ 

請建議是否有可用的轉置行到列的任何優化的直接API。 我的輸入數據量是相當大的,所以像collect這樣的動作,我無法執行,因爲它會佔用驅動程序上的所有數據。 我正在使用Spark 2.x

+0

如果'entry'具有所有3個'EncounterID'的值,該怎麼辦?只能有3個'EncounterID'嗎? – philantrovert

+0

條目將只有一個值。並且是EncounterID是固定的,將只有3個EncounterID。 – Kalpesh

+1

你確定這是你期望的結果嗎?所有三個Encounter列總是具有相同的值... – Oli

回答

0

我不確定您需要的是您實際詢問的內容。然而,以防萬一這裏是一個想法:

val entries = inputDF.where('entry isNotNull) 
    .where('entry !== "") 
    .select("MemberID", "entry").distinct 

val df = inputDF.groupBy("MemberID") 
    .agg(collect_list("EncounterID") as "encounterList") 
    .join(entries, Seq("MemberID")) 
df.show 
+--------+-------------------------+-----+ 
|MemberID|   encounterList |entry| 
+--------+-------------------------+-----+ 
| pid1|  [enc2, enc1, enc3]| bat| 
| pid3|    [enc2, enc1]| cat| 
+--------+-------------------------+-----+ 

列表的順序是不確定的,但你可以對它進行排序,然後從它.withColumn("Encounter1", sort_array($"encounterList")(0))提取新列...

其他的想法

如果你想要的是擺在相應的「遭遇」列項的值,你可以使用透視:

inputDF 
    .groupBy("MemberID") 
    .pivot("EncounterID", Seq("enc1", "enc2", "enc3")) 
    .agg(first("entry")).show 

+--------+----+----+----+ 
|MemberID|enc1|enc2|enc3| 
+--------+----+----+----+ 
| pid1| bat| | | 
| pid3| cat| | | 
+--------+----+----+----+ 

Seq("enc1", "enc2", "enc3")添加爲optionnal,但由於您知道列的內容,因此它將加速計算。

+0

對不起,我不能夠硬編碼的值,這將取決於列中有什麼值。還有一件事我錯過了添加..如果對於特定的memberID只有2行可用,那麼代碼應該能夠將第三列標記爲空。 ..我會更新這個問題 – Kalpesh

相關問題