Spark Scala GroupBy列和总和值

时间:2018-03-30 13:06:16

标签: scala apache-spark rdd

我是Apache-spark的新手,最近开始使用Scala进行编码。

我有一个包含4列的RDD,如下所示: (第1栏 - 名称,2个标题,3个视图,4个大小)

aa    File:Sleeping_lion.jpg 1 8030
aa    Main_Page              1 78261
aa    Special:Statistics     1 20493
aa.b  User:5.34.97.97        1 4749
aa.b  User:80.63.79.2        1 4751
af    Blowback               2 16896
af    Bluff                  2 21442
en    Huntingtown,_Maryland  1 0

我想根据列名进行分组,并获得列视图的总和。

应该是这样的:

aa   3
aa.b 2
af   2
en   1

我尝试使用groupByKeyreduceByKey,但我陷入困境,无法继续前进。

2 个答案:

答案 0 :(得分:1)

我假设您已经填充了RDD。

   //For simplicity, I build RDD this way
      val data = Seq(("aa", "File:Sleeping_lion.jpg", 1, 8030),
          ("aa", "Main_Page", 1, 78261),
          ("aa", "Special:Statistics", 1, 20493),
          ("aa.b", "User:5.34.97.97", 1, 4749),
          ("aa.b", "User:80.63.79.2", 1, 4751),
          ("af", "Blowback", 2, 16896),
          ("af", "Bluff", 2, 21442),
          ("en", "Huntingtown,_Maryland", 1, 0))

数据框架方法

  val sql = new SQLContext(sc)        
  import sql.implicits._
  import org.apache.spark.sql.functions._

  val df = data.toDF("name", "title", "views", "size")      
  df.groupBy($"name").agg(count($"name") as "") show

**Result** 
+----+-----+
|name|count|    
+----+-----+    
|  aa|    3|    
|  af|    2|   
|aa.b|    2|    
|  en|    1|    
+----+-----+

RDD方法(CountByKey(...))

rdd.keyBy(f => f._1).countByKey().foreach(println(_))

RDD方法(reduceByKey(...))

rdd.map(f => (f._1, 1)).reduceByKey((accum, curr) => accum + curr).foreach(println(_))

如果其中任何一项都无法解决您的问题,请分享您已经捣乱的地方。

答案 1 :(得分:0)

这应该有效,你读取文本文件,用分隔符拆分每一行,用适当的文件映射到键值并使用countByKey:

sc.textFile("path to the text file")
 .map(x => x.split(" ",-1))
 .map(x => (x(0),x(3)))
 .countByKey

要完成我的回答,您可以使用dataframe api解决问题(如果您可以根据spark版本进行此操作),例如:

val result = df.groupBy("column to Group on").agg(count("column to count on"))

另一种可能性是使用sql方法:

val df = spark.read.csv("csv path")
df.createOrReplaceTempView("temp_table")
val result = sqlContext.sql("select <col to Group on> , count(col to count on) from temp_table Group by <col to Group on>")