假设我们有几个列表:
List(List(1,2,3), List(4,5,6), List(7,8,9))
如何获得所有列表中每个元素的平均值?在这种情况下,我们将有
List((1+4+7)/3, (2+5+8)/3, (3+6+9)/3)
在这里。
答案 0 :(得分:3)
假设你想要第一个元素的平均值,然后是所有第二个元素的平均值,等等:
List( List(1,2,3), List(4,5,6), List(7,8,9) ).transpose.map(x => x.sum/x.size.toDouble)
>res: List[Double] = List(4.0, 5.0, 6.0)
答案 1 :(得分:1)
@marios的答案很好,但如果子列表长度不一样怎么办?在这种情况下,transpose
将抛出:
java.lang.IllegalArgumentException:transpose需要所有集合 具有相同的大小
假设您仍然想要所有第n个值的平均值,即使并非所有子列表都有n个元素,这也应该有效。
def getAvgs(lli: List[List[Int]]): List[Double] =
if (lli.isEmpty) Nil
else {
val heads = lli.flatMap(_.headOption)
heads.sum.toDouble / heads.length :: getAvgs(lli.filter(_.length > 1).map(_.tail))
}
getAvgs(List(List(20,2,3,7), List(3,4), List(4,6,10)))
// res0: List[Double] = List(9.0, 4.0, 6.5, 7.0)
答案 2 :(得分:1)
val listOfLists = List( List(1,2,3), List(4,5,6), List(7,8,9) )
// listOfLists: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
// if you wanted a simple avg
val listOfAvg = listOfLists.map(list => list.sum.toDouble / list.length)
// listOfAvg: List[Double] = List(2.0, 5.0, 8.0)
假设您希望获得i
个元素的平均值,
val listOfIthAvg = listOfLists
.flatMap(list => list.zipWithIndex)
.groupBy({ case (i, index) => index })
.map({ case (index, group) =>
(index, group.map(_._1).sum.toDouble / group.length)
})
.toList
.sortBy({ case (index, average) => index })
.map({ case (index, average) => average })
答案 3 :(得分:0)
使用scala列表(Rubio的回答是动态的):
scala> val dl =List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9), List(10, 11, 12))
scala> dl.transpose.map(_.sum/dl.length)
res5: List[Int] = List(5, 6, 7)
在Spark中使用Scala:
val valRDD = sc.parallelize(List((1,2,3), (4,5,6), (7,8,9)))
valRDD.map(x => (1, (x._1, x._2, x._3, 1)))
.reduceByKey( (x,y) => (x._1+y._1, x._2+y._2, x._3+y._3, x._4+y._4) )
.map(x=> ((x._2._1/x._2._4), (x._2._2/x._2._4), (x._2._3/x._2._4)))
.take(5).foreach(println)
输出:(4,5,6)