如何合并多行中的值以便可以一起处理-Spark scala

如何合并多行中的值以便可以一起处理-Spark scala,scala,apache-spark,dataframe,merge,Scala,Apache Spark,Dataframe,Merge,我每个personId有多个数据库行,其中的列可能有值,也可能没有值-我在这里使用颜色,因为数据是文本而不是数字,因此不适合内置聚合函数。一个简化的例子是 PersonId ColA ColB ColB 100 red 100 green 100 gold 100 green 110 yellow 110 white 1

我每个personId有多个数据库行,其中的列可能有值,也可能没有值-我在这里使用颜色,因为数据是文本而不是数字,因此不适合内置聚合函数。一个简化的例子是

PersonId    ColA    ColB    ColB
100         red
100                 green
100                         gold
100         green
110                 yellow
110         white
110   
120         
etc...
我希望能够在函数中决定每个唯一PersonId使用哪个列数据。如果数据的每列没有多个值(颜色),那么表上针对自身的三向联接将是一个很好的解决方案。例如,该联接将3行合并为一行,但仍生成多行

PersonId    ColA    ColB    ColB
100         red     green   gold
100         green                                   
110         white   yellow
110   
120
因此,我正在寻找的解决方案将允许我在一个位置(函数)处理一个人的所有值(颜色),以便在他们的所有数据中做出决策。 当然,真实数据有更多的列,但此决策的主要列是三列。数据在Scala Spark中作为数据帧读取,我更喜欢使用API而不是sql。我不知道是否有任何外来的窗口或groupby函数会有所帮助,或者它是否会归结为普通的旧迭代和累积。
[中使用的技术可能适用,但这是一个小小的飞跃。

考虑使用customUDF来实现这一点

import org.apache.spark.sql.functions._
val df = Seq((100, "red", null, null), (100, null, "white", null), (100, null, null, "green"), (200, null, "red", null)).toDF("PID", "A", "B", "C")

df.show()
+---+----+-----+-----+
|PID|   A|    B|    C|
+---+----+-----+-----+
|100| red| null| null|
|100|null|white| null|
|100|null| null|green|
|200|null|  red| null|
+---+----+-----+-----+

val customUDF = udf((array: Seq[String]) => {
    val newts = array.filter(_.nonEmpty)
    if  (newts.size == 0) null
    else newts.head
})

df.groupBy($"PID").agg(customUDF(collect_set($"A")).as("colA"), customUDF(collect_set($"B")).as("colB"), customUDF(collect_set($"C")).as("colC")).show

+---+----+-----+-----+
|PID|colA| colB| colC|
+---+----+-----+-----+
|100| red|white|green|
|200|null|  red| null|
+---+----+-----+-----+



我没有时间给出完整的答案,但是你有没有研究过滞后/超前或其他窗口操作?为什么在这个例子中,100的第二行是绿色的,第一行是红绿色的金,而不是第一行是红色的,第二行是绿绿色的金?你能解释一下你想要如何组合它们吗?这只是说明了三路连接可能产生的效果我最初认为是三向(自我)join只返回1行,除非每列在其他行中具有不同的值,否则它会返回1行。真正的问题只是处理跨多行和多列的数据。我主要在Java Spark中使用RDD,在这种环境中,您可以首先使用“flatMap”将此RDD映射到成对的RDD中,其中PersonID作为t键和另一列表示与键相关的颜色。然后您可以“按键添加”,并将得到您需要的。如果您认为这种方法可能有帮助,我可以详细说明。请这样做,这听起来很有希望-尽管我需要有三条信息:人名、颜色和颜色所在的列。哪种颜色选择哪个列是重要的。