【问题标题】:dataframe: how to groupBy/count then filter on count in Scala数据框:如何在 Scala 中分组/计数然后过滤计数
【发布时间】:2015-11-14 04:41:21
【问题描述】:

火花 1.4.1

我遇到一种情况,即按数据框分组,然后对“计数”列进行计数和过滤会引发以下异常

import sqlContext.implicits._
import org.apache.spark.sql._

case class Paf(x:Int)
val myData = Seq(Paf(2), Paf(1), Paf(2))
val df = sc.parallelize(myData, 2).toDF()

然后分组过滤:

df.groupBy("x").count()
  .filter("count >= 2")
  .show()

抛出异常:

java.lang.RuntimeException: [1.7] failure: ``('' expected but `>=' found count >= 2

解决方案:

重命名列会使问题消失(因为我怀疑与内插的“计数”函数没有冲突”

df.groupBy("x").count()
  .withColumnRenamed("count", "n")
  .filter("n >= 2")
  .show()

那么,这是预期的行为、错误还是有规范的解决方法?

谢谢,亚历克斯

【问题讨论】:

    标签: scala apache-spark apache-spark-sql


    【解决方案1】:

    那么,这是一个预期的行为,一个错误

    说实话,我不确定。看起来解析器将count 解释为不是列名而是一个函数,并且需要后面的括号。看起来像是一个错误,或者至少是解析器的严重限制。

    有没有规范的方法?

    Hermanmattinbits 已经提到了一些选项,所以这里我提供了更多 SQLish 方法:

    import org.apache.spark.sql.functions.count
    
    df.groupBy("x").agg(count("*").alias("cnt")).where($"cnt"  > 2)
    

    【讨论】:

    • 如何显示所有列而不是 X 列和 CNT 列?
    • @abu-shoeb 您可以将agg(...) 与多个表达式一起使用。一种常见的模式是对您要显示的所有其他列使用min(name),并给出每组中列的最小值。您必须明确列出所有列。
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      当您将字符串传递给filter 函数时,该字符串被解释为SQL。 Count 是一个 SQL 关键字,使用 count 作为变量会使解析器感到困惑。这是一个小错误(如果您愿意,可以提交 JIRA 票证)。

      您可以通过使用列表达式而不是字符串来轻松避免这种情况:

      df.groupBy("x").count()
        .filter($"count" >= 2)
        .show()
      

      【讨论】:

      • 如果我将过滤器表达式更改为 '==' ,为什么它不起作用?
      • @sqlconsumer.net 使用'==='
      猜你喜欢
      • 1970-01-01
      • 2014-10-23
      • 2016-11-26
      • 2019-11-23
      • 2011-10-11
      • 2017-06-08
      • 1970-01-01
      • 2014-01-06
      • 1970-01-01
      相关资源
      最近更新 更多