Spark数据帧聚合scala
Posted
技术标签:
【中文标题】Spark数据帧聚合scala【英文标题】:Spark dataframe aggregation scala 【发布时间】:2017-03-09 21:42:47 【问题描述】: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
我知道 col1 上的 groupBy 并获得 col2 的最大值。我可以使用df.groupBy("col1").agg("col2"->"max")
但我的要求是如果有 null 我想选择该记录,但如果没有 null 我想选择 col2 的最大值。
我该怎么做,请帮助我。
【问题讨论】:
尝试使用这个import org.apache.spark.sql.functions._
df.groupBy("col1").agg(collect_as_list("col2"))
现在你在 col2 上有列表试试你的逻辑,比如 if list.contains(null) return null else max from list
你真的应该重新考虑问题的前提。没有必要在你的 RDD 中有一堆null
。
大家好,感谢您的回复。我已经通过以下方式做到了这一点。我首先通过将空值更新为该列的字符串“99-99-9999”来修改数据框。然后我按其他列和 agg -->max 对我更新的列进行了分组。这样我的要求就满足了。非常感谢所有回复的人。
@Ramesh :如果您发布答案并接受它会很好。因此,如果其他人正在寻找类似的答案,这将是有帮助的。
【参考方案1】:
正如我所评论的,您对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
,这样我就可以享受更多的类型安全。我将 null
替换为 MaxValue
,原因我稍后会解释。
然后我 groupBy
像你一样,然后我 map
在组上将键与值的最大值配对,这将是你的原始数据项之一或 MaxValue
其中@987654333 @s 曾经是。如果必须,您可以将它们转回null
,但我不会。
可能有一种更简单的方法来完成这一切,但我喜欢将null
替换为MaxValue
,这种模式匹配可以帮助我缩小类型范围,而且之后我可以将所有内容都视为相同。
【讨论】:
以上是关于Spark数据帧聚合scala的主要内容,如果未能解决你的问题,请参考以下文章
Spark多个动态聚合函数,countDistinct不起作用
如何使用 spark-scala 在 spark 数据帧上执行枢轴?