Dataframe: как groupBy/count, затем фильтровать счетчик в Scala

Искра 1.4.1

Я сталкиваюсь с ситуацией, когда группировка с помощью фрейма данных, тогда подсчет и фильтрация в столбце "count" вызывает исключение ниже

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

Решение:

Переименование столбца заставляет проблему исчезнуть (поскольку, как я подозреваю, нет никакого конфликта с интерполированной функцией "count"

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

Итак, это поведение, которое можно ожидать, ошибка или есть канонический способ обойти?

спасибо, alex

Ответы

Ответ 1

Когда вы передаете строку функции filter, строка интерпретируется как SQL. Count является ключевым словом SQL и использует count, поскольку переменная смущает парсер. Это небольшая ошибка (вы можете подать билет JIRA, если хотите).

Вы можете легко избежать этого, используя выражение столбца вместо строки:

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

Ответ 2

Итак, это то, что нужно ожидать, ошибка

Правду сказать, что нет. Похоже, что синтаксический анализатор интерпретирует count не как имя столбца, а функцию и ожидает следующих скобок. Похож на ошибку или, по крайней мере, серьезное ограничение анализатора.

существует ли канонический способ передвижения?

Некоторые параметры уже упоминались Herman и mattinbits, поэтому здесь более SQLish-подход от меня:

import org.apache.spark.sql.functions.count

df.groupBy("x").agg(count("*").alias("cnt")).where($"cnt"  > 2)