Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何聚合+;scala中的分组?_Scala - Fatal编程技术网

如何聚合+;scala中的分组?

如何聚合+;scala中的分组?,scala,Scala,我有以下数据: val Cars_tmp = List("Cars|10|Paris|5|Type|New|3", "Cars|15|Paris|3|Type|New|5", "Cars|20|London|10|Type|New|2", "Cars|40|London|40|Type|New|1") 我想计算每个城市的平均汽车数量。 请注意: 汽车数量(6)=汽车数量和汽车数量(2).汽车数量(2)=城市 我试过

我有以下数据:

val Cars_tmp = List("Cars|10|Paris|5|Type|New|3", "Cars|15|Paris|3|Type|New|5", "Cars|20|London|10|Type|New|2", "Cars|40|London|40|Type|New|1")
我想计算每个城市的平均汽车数量。 请注意: 汽车数量(6)=汽车数量和汽车数量(2).汽车数量(2)=城市

我试过这个:

          val aggregate = Cars_tmp.map(r => r.split("[|]")(6).toInt).par.aggregate((0, 0))(

          (s, r) =>(s._1 + r , s._2 + 1),

          (s,r) => (s._1 + r._1, s._2 + r._2)
          )

        val average: Float = aggregate._1.toFloat/ aggregate._2.toFloat

        println("aggregate value" + aggregate)
        println("average value" + average)
我有以下结果:

aggregate value (11,4)
average value 2.75
这将计算平均汽车数量。 我怎样才能包括按城市分组(按汽车分组)分割(“|”)(2))

谢谢你的回答

Cars_tmp
  .map(x => {
    (x.split('|')(2), x.split('|')(6).toInt)
  })
  .groupBy { case (city, _) => city }
  .map { case (_, xs) =>
    xs
      .map(x => x._2)
      .foldLeft(0.0f) { case (acc, x) => acc + (x / xs.size.toFloat) }
  }
您可以提取(城市,汽车数量)的两个元组,然后使用
groupBy
创建
Map[String,List[(String,Int)]
,其中键为城市,值为汽车数量序列

然后使用
map
计算平均值

结果是:

List(1.5F, 4.0F)
使用
df(“城市”、“全国广播公司”)

检查平均聚合函数:


scala doc:

谢谢您的回答。这对我很有帮助。
mapValues
是懒惰的,所以这会在每次访问地图时计算
xs.map(u._2).sum.toFloat/xs.length
(代码在很多方面都非常低效)@LuisMiguelMejíaSuárez感谢您指出。实际上,在这种情况下,
transform
更好,因为
mapValues
将重新计算每次访问的平均值。我编辑了我的答案。还有什么其他方法可以提高性能?@etherealyn什么是
转换
?也许你的意思是地图其他提高性能的方法包括使用
foldLeft
而不是
sum
size
一次性计算平均值,以及将列表转换为
map
+
groupBy
之前的懒散列表,一次性执行这两个操作。谢谢您的回答。目前我只在Scala工作,不使用Spark。你有只使用Scala的想法吗?这是Scala。如果你不使用spark,为什么要使用ApacheSpark?我更喜欢使用Scala。但我不知道使用Scala是否可以进行聚合,是否必须使用Spark。这就是为什么我用Spark来标记它,以使它有其他的想法。而且我有一个列表,而不是一个数据框。首先,我必须将列表转换为DataFrame。val a=sc.parallelize(Cars_tmp)val b=a.map(x=>x.split(“|”).toDF.show(false)b.printSchema。我在数据帧中有一个元素数组,要进行解决方案中提到的攻击并不容易。将该字符串解析为一个case类,这样处理就更容易了。@LuisMiguelMejíaSuárez感谢您的回答。好的,我试试看。@LuisMiguelMejíaSuárez你能用一个例子解释一下你将如何使用case类吗?
df
.groupBy("city")
.agg(
  avg(col("nbCars")).as("average_nb_cars")
)