2017-03-09 185 views
0

val df = sc.parallelize(Seq((a, 1), (a, null), (b, null)(b, 2),(b, 3),(c, 2),(c, 4),(c, 3))).toDF("col1","col2")火花数据帧聚合阶

输出应该是这样的下方。 col1 col2 a null b null c 4 我知道col在col1上获得col2的最大值。我可以使用df.groupBy("col1").agg("col2"->"max")

但我的要求是,如果空有我想选择该记录,但如果null不存在,我想选择col2的最大值。

我该如何做到这一点,任何请帮助我。

+0

尝试使用此 '进口org.apache.spark.sql.functions._' 'df.groupBy( “COL1”)。AGG(collect_as_list( “COL2”))'现在你有COL2名单试试这里的逻辑,如果list.contains(null)返回null否则从列表中的最大值 –

+0

你应该真的重新考虑问题的前提。 RDD中不需要有一堆'null'。 – Vidya

+0

大家好,谢谢你的回复。我以下面的方式完成了这项工作。我首先通过将null值更新为该列的字符串'99 -99-9999'来修改数据框。然后我在其他列上做了一个组,并在我更新的列上使用了agg - > max。所以我的要求得到满足。非常感谢所有回应的人。 – Ramesh

回答

0

正如我评论,你的null使用使事情不必要的问题,所以如果你能不null摆在首位不行,我觉得最有意义把它变成更有用的东西:

val df = sparkContext.parallelize(Seq((a, 1), (a, null), (b, null), (b, 2),(b, 3),(c, 2),(c, 4),(c, 3))) 
     .mapValues { v => Option(v) match { 
      case Some(i: Int) => i 
      case _ => Int.MaxValue 
      } 
     }.groupBy(_._1).map { 
      case (k, v) => k -> v.map(_._2).max 
     } 

首先,我用Option摆脱null,并将东西从Any下移到Int,这样我就可以享受更多的类型安全。我将用MaxValue代替null,原因我马上解释。

然后我groupBy像你一样,后来我map在组与值的最大值,这要么是你原来的数据项的一个或MaxValue其中null一度是配对的钥匙。如果你必须,你可以把它们变回null,但我不会。

有可能是做这一切更简单的方法,但我喜欢null替换MaxValue,模式匹配,这有助于我缩小类型,而事实上我可以把一切都同算账。