web-dev-qa-db-ja.com

データフレーム:Scalaでグループ化/カウントしてからカウントでフィルターする方法

Spark 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

解決策:

列の名前を変更すると、問題はなくなります(補間された「カウント」関数と競合しないと思われるため)

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

だから、それは予想される動作、バグ、または回避するための標準的な方法がありますか?

ありがとう、アレックス

35
user3646671

filter関数に文字列を渡すと、文字列はSQLとして解釈されます。カウントはSQLキーワードであり、変数としてcountを使用すると、パーサーが混乱します。これは小さなバグです(必要に応じてJIRAチケットを提出できます)。

これを簡単に回避するには、文字列の代わりに列式を使用します。

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

だから、それは予想される動作、バグです

真実はわからない。パーサーはcountを列名ではなく関数として解釈し、次の括弧を想定しているようです。バグまたは少なくともパーサーの重大な制限のように見えます。

移動する標準的な方法はありますか?

Hermanmattinbits でいくつかのオプションが既に言及されているので、ここで私からのよりSQLishのアプローチ:

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

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

解決策はバックティックにカウントすることだと思います

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

http://mail-archives.us.Apache.org/mod_mbox/spark-user/201507.mbox/%3C8E43A71610EAA94A9171F8AFCC44E351B48EDF@fmsmsx124.amr.corp.intel.com%3E

10
mattinbits