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)
Ответ 3
Я думаю, что решение состоит в том, чтобы поместить count в обратные тики
.filter("`count` >= 2")
http://mail-archives.us.apache.org/mod_mbox/spark-user/201507.mbox/%[email protected]l.com%3E