2017-12-27 293 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

相关问题