如何在Scala中获得多个列表的平均值

如何在Scala中获得多个列表的平均值,scala,Scala,假设我们有几个列表: List(List(1,2,3), List(4,5,6), List(7,8,9)) 如何获得所有列表中每个元素的平均值?在这种情况下,我们将 这里列出((1+4+7)/3,(2+5+8)/3,(3+6+9)/3) 来自@marios的答案很好,但是如果子列表的长度不尽相同呢?在这种情况下,转置将抛出: java.lang.IllegalArgumentException:转置需要所有集合 大小一样 假设您仍然需要所有第n个值的平均值,即使不是所有子列表都有n个元素,这

假设我们有几个列表:

List(List(1,2,3), List(4,5,6), List(7,8,9))
如何获得所有列表中每个元素的平均值?在这种情况下,我们将
这里列出((1+4+7)/3,(2+5+8)/3,(3+6+9)/3)

来自@marios的答案很好,但是如果子列表的长度不尽相同呢?在这种情况下,
转置
将抛出:

java.lang.IllegalArgumentException:转置需要所有集合 大小一样

假设您仍然需要所有第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)
使用scala列表(Rubio的答案是动态的):

在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)

假设需要第一个元素的平均值,然后是所有第二个元素的平均值,以此类推:

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)
假设您想要得到
i
th元素的平均值

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 })

我不认为OP要求的是Spark解决方案为什么要引入转置限制。。。还有,你怎么知道列表的长度是3?为什么你认为转置是一种限制?对,3的长度是不正确的。如果知道列表的长度相同,那么转置是非常好的。如果没有,那么@jwvh所拥有的就更完整了。你不能把这些列表映射成一个和,然后除以长度吗?这个密码需要什么?@SarveshKumarSingh,再看看这个问题和marios的答案。OP需要每个子列表中所有第一个元素的平均值,以及所有第二个元素、第三个元素等。我建议的解决方案提供所有第N个元素的平均值,即使不是所有子列表都有N个元素。在我的示例输出中,只有一个第四个元素,因此平均所有第四个元素的结果是
7/1=7.0
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)
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 })