データを集約するさまざまな方法を比較しようとしています。
これは、2つの要素(ページ、訪問者)を持つ私の入力データです。
(PAG1,V1)
(PAG1,V1)
(PAG2,V1)
(PAG2,V2)
(PAG2,V1)
(PAG1,V1)
(PAG1,V2)
(PAG1,V1)
(PAG1,V2)
(PAG1,V1)
(PAG2,V2)
(PAG1,V3)
Sparkこのコードを使用したSQLへのSQLコマンドの操作:
import sqlContext.implicits._
case class Log(page: String, visitor: String)
val logs = data.map(p => Log(p._1,p._2)).toDF()
logs.registerTempTable("logs")
val sqlResult= sqlContext.sql(
"""select page
,count(distinct visitor) as visitor
from logs
group by page
""")
val result = sqlResult.map(x=>(x(0).toString,x(1).toString))
result.foreach(println)
私はこの出力を取得します:
(PAG1,3) // PAG1 has been visited by 3 different visitors
(PAG2,2) // PAG2 has been visited by 2 different visitors
ここで、Dataframesとthiers APIを使用して同じ結果を取得したいのですが、同じ出力を取得できません。
import sqlContext.implicits._
case class Log(page: String, visitor: String)
val logs = data.map(p => Coppia(p._1,p._2)).toDF()
val result = log.select("page","visitor").groupBy("page").count().distinct
result.foreach(println)
実際、それは私が出力として得るものです:
[PAG1,8] // just the simple page count for every page
[PAG2,4]
それはおそらく馬鹿げたものですが、私は今それを見ることができません。
前もって感謝します!
FF
必要なのは、DataFrame集約関数countDistinct
です:
import sqlContext.implicits._
import org.Apache.spark.sql.functions._
case class Log(page: String, visitor: String)
val logs = data.map(p => Log(p._1,p._2))
.toDF()
val result = logs.select("page","visitor")
.groupBy('page)
.agg('page, countDistinct('visitor))
result.foreach(println)
これを行うには、データフレームのgroupBy
コマンドを2回使用できます。ここに、 df1
は元の入力です。
val df2 = df1.groupBy($"page",$"visitor").agg(count($"visitor").as("count"))
このコマンドは次の結果を生成します。
page visitor count
---- ------ ----
PAG2 V2 2
PAG1 V3 1
PAG1 V1 5
PAG1 V2 2
PAG2 V1 2
次に、groupBy
コマンドを再度使用して、最終結果を取得します。
df2.groupBy($"page").agg(count($"visitor").as("count"))
最終出力:
page count
---- ----
PAG1 3
PAG2 2