Kal*_*esh 2 transpose scala apache-spark apache-spark-sql
有什么方法可以将数据帧行转换为列。我有以下结构作为输入:
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|
+--------+----------+----------+----------+-----+
Run Code Online (Sandbox Code Playgroud)
请建议是否有任何优化的直接 API 可用于将行转换为列。我的输入数据量非常大,所以像收集这样的操作,我将无法执行,因为它会占用驱动程序上的所有数据。我正在使用 Spark 2.x
我不确定您需要的是您实际询问的内容。然而,以防万一这里有一个想法:
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|
+--------+-------------------------+-----+
Run Code Online (Sandbox Code Playgroud)
列表的顺序不是确定性的,但您可以对其进行排序,然后使用.withColumn("Encounter1", sort_array($"encounterList")(0))...
其他想法
如果您想要将 entry 的值放在相应的“Encounter”列中,则可以使用数据透视:
inputDF
.groupBy("MemberID")
.pivot("EncounterID", Seq("enc1", "enc2", "enc3"))
.agg(first("entry")).show
+--------+----+----+----+
|MemberID|enc1|enc2|enc3|
+--------+----+----+----+
| pid1| bat| | |
| pid3| cat| | |
+--------+----+----+----+
Run Code Online (Sandbox Code Playgroud)
添加Seq("enc1", "enc2", "enc3")是可选的,但由于您知道列的内容,它将加快计算速度。
| 归档时间: |
|
| 查看次数: |
9918 次 |
| 最近记录: |