wake-up-neo.com

dataframe: wie gruppiert man nach / count und filtert dann nach count in Scala

Spark 1.4.1

Ich stoße auf eine Situation, in der das Gruppieren nach einem Datenrahmen, das Zählen und Filtern in der Spalte 'count' die folgende Ausnahme auslöst

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()

Dann gruppieren und filtern:

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

Löst eine Ausnahme aus:

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

Lösung:

Durch das Umbenennen der Spalte verschwindet das Problem (da ich vermute, dass es keinen Konflikt mit der interpolierten 'count'-Funktion gibt).

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

Also, ist das ein zu erwartendes Verhalten, ein Bug oder gibt es einen kanonischen Weg, um das zu umgehen?

danke alex

35
user3646671

Wenn Sie eine Zeichenfolge an die Funktion filter übergeben, wird die Zeichenfolge als SQL interpretiert. Count ist ein SQL-Schlüsselwort und die Verwendung von count als Variable verwirrt den Parser. Dies ist ein kleiner Fehler (Sie können ein JIRA-Ticket einreichen, wenn Sie möchten).

Sie können dies leicht vermeiden, indem Sie anstelle eines Strings einen Spaltenausdruck verwenden:

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

Ist das ein zu erwartendes Verhalten, ein Fehler?

Um ehrlich zu sein bin ich mir nicht sicher. Anscheinend interpretiert der Parser count nicht als Spaltenname, sondern als Funktion und erwartet die folgenden Klammern. Sieht aus wie ein Fehler oder zumindest eine ernsthafte Einschränkung des Parsers.

gibt es einen kanonischen Weg, um herumzukommen?

Einige Optionen wurden bereits von Herman und mattinbits erwähnt, also hier mehr SQLish Ansatz von mir:

import org.Apache.spark.sql.functions.count

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

Ich denke, eine Lösung besteht darin, die Back Ticks zu zählen

.filter("`count` >= 2")

http://mail-archives.us.Apache.org/mod_mbox/spark-user/201507.mbox/%[email protected]l.com%3E

10
mattinbits