如何将第一个列表中的每个元素添加到 Scala 中的相应列表?
How can I add each element in first list with the corresponding list in Scala?
所以我有一个列表:
var data = List(
List(Some(313.062468), Some(27.847252), Some(29.847252)),
List(Some(301.873641), Some(42.884065), Some(89.847252)),
List(Some(332.373186), Some(53.509768), Some(10.847252))
)
如何计算基本函数,例如:
对于每个列表的每个元素:
第一行
Some(301.873641) - Some(313.062468) / Some(313.062468)
Some(332.373186) - Some(301.873641) / Some(301.873641)
第二栏
Some(42.884065) - Some(27.847252) / Some(27.847252)
Some(53.509768) - Some(42.884065) / Some(42.884065)
第三栏
Some(89.847252) - Some(29.847252) / Some(29.847252)
Some(10.847252) - Some(89.847252) / Some(89.847252)
我目前卡在这里
data.map(_.head).foreach {
case i => println(i)
}
这只打印每个嵌套列表的头部。我不知道如何获取嵌套元素的每个元素并进行上述计算
结果应该是这样的:
List(
List(Some(-0.03573991820699504), Some(0.5399747522663995), Some(88.847252) )
List(Some(0.10103414428290529), Some(0.24777742035415723), Some(9.847252) )
)
您可能希望从使用 transpose
方法开始,并从那里开始您需要的逻辑。以下是对示例数据调用 transpose
的结果:
scala> data.transpose.foreach(println)
List(Some(313.062468), Some(301.873641), Some(332.373186))
List(Some(27.847252), Some(42.884065), Some(53.509768))
List(Some(29.847252), Some(89.847252), Some(10.847252))
转置、展平和压缩
val list = data.transpose.flatMap(_.flatten)
list.tail zip list map { case (a, b) => (b - a)/b }
scala> val list = data.transpose.flatMap(_.flatten)
list: List[Double] = List(313.062468, 301.873641, 332.373186, 27.847252, 42.884065, 53.509768, 29.847252, 89.847252, 10.847252)
Scala REPL
scala> list.tail zip list map { case (a, b) => (b - a)/b }
res19: List[Double] = List(0.03573991820699504, -0.10103414428290529, 0.9162169116734945, -0.5399747522663995, -0.24777742035415723, 0.4422092803691468, -2.010235314125401, 0.8792700749489812)
不是一个巧妙的解决方案,但有效
data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten.map { case (a, b) => (b - a)/b}
重要的代码行。
scala> data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten
res4: List[(Double, Double)] = List((313.062468,301.873641), (27.847252,42.884065), (29.847252,89.847252), (301.873641,332.373186), (42.884065,53.509768), (89.847252,10.847252))
scala> data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten.map { case (a, b) => (b - a)/b}
res5: List[Double] = List(-0.037064604126863805, 0.35063870460974256, 0.6678000569232768, 0.09176295286347183, 0.19857501531309202, -7.282950557431505)
Scala REPL
scala> var data = List(
| List(Some(313.062468), Some(27.847252), Some(29.847252)),
| List(Some(301.873641), Some(42.884065), Some(89.847252)),
| List(Some(332.373186), Some(53.509768), Some(10.847252))
| )
data: List[List[Some[Double]]] = List(List(Some(313.062468), Some(27.847252), Some(29.847252)), List(Some(301.873641), Some(42.884065), Some(89.847252)), List(Some(332.373186), Some(53.509768), Some(10.847252)))
scala> data.zip(data.tail)
res0: List[(List[Some[Double]], List[Some[Double]])] = List((List(Some(313.062468), Some(27.847252), Some(29.847252)),List(Some(301.873641), Some(42.884065), Some(89.847252))), (List(Some(301.873641), Some(42.884065), Some(89.847252)),List(Some(332.373186), Some(53.509768), Some(10.847252))))
scala> data.zip(data.tail).map { case (alist, blist) => alist zip blist }
res1: List[List[(Some[Double], Some[Double])]] = List(List((Some(313.062468),Some(301.873641)), (Some(27.847252),Some(42.884065)), (Some(29.847252),Some(89.847252))), List((Some(301.873641),Some(332.373186)), (Some(42.884065),Some(53.509768)), (Some(89.847252),Some(10.847252))))
scala> data.zip(data.tail).map { case (alist, blist) => alist zip blist }.flatten
res2: List[(Some[Double], Some[Double])] = List((Some(313.062468),Some(301.873641)), (Some(27.847252),Some(42.884065)), (Some(29.847252),Some(89.847252)), (Some(301.873641),Some(332.373186)), (Some(42.884065),Some(53.509768)), (Some(89.847252),Some(10.847252)))
scala> data.zip(data.tail).map { case (alist, blist) => alist zip blist }.flatten
res3: List[(Some[Double], Some[Double])] = List((Some(313.062468),Some(301.873641)), (Some(27.847252),Some(42.884065)), (Some(29.847252),Some(89.847252)), (Some(301.873641),Some(332.373186)), (Some(42.884065),Some(53.509768)), (Some(89.847252),Some(10.847252)))
scala> data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten
res4: List[(Double, Double)] = List((313.062468,301.873641), (27.847252,42.884065), (29.847252,89.847252), (301.873641,332.373186), (42.884065,53.509768), (89.847252,10.847252))
scala> data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten.map { case (a, b) => (b - a)/b}
res5: List[Double] = List(-0.037064604126863805, 0.35063870460974256, 0.6678000569232768, 0.09176295286347183, 0.19857501531309202, -7.282950557431505)
转置列表,然后使用 .sliding(2)
获得元素的滚动 windows:
scala> def diffPercent(o1: Option[Double], o2: Option[Double]) = (o1, o2) match {
case (Some(d1), Some(d2)) => Some((d2 - d1) / d1) // need to handle d1 == 0 too
case _ => None
}
diffPercent: (o1: Option[Double], o2: Option[Double])Option[Double]
// sample value before the final operation
scala> data.transpose.map(_.sliding(2).toList) // .toList to show the values in REPL
res13: List[List[List[Some[Double]]]] = List(List(List(Some(313.062468), Some(301.873641)), List(Some(301.873641), Some(332.373186))), ...)
scala> data.transpose.map(_.sliding(2).map {
case o1 :: o2 :: Nil => diffPercent(o1, o2)
case _ => None // source has less than 2 elems
}.toList).transpose // transpose back the list
res17: List[List[Option[Double]]] = List(List(Some(-0.03573991820699504), Some(0.5399747522663995), Some(2.010235314125401)), List(Some(0.10103414428290529), Some(0.24777742035415723), Some(-0.8792700749489812)))
这个比其他的简单一点,没有使用transpose
。它非常接近@pamu 的。我从@Marth 的回答中借用了diffPercent
。
data.sliding(2)
.map{case List(a, b) => (a zip b).map {case (x,y) => diffPercent(x,y)}}
.toList
所以我有一个列表:
var data = List(
List(Some(313.062468), Some(27.847252), Some(29.847252)),
List(Some(301.873641), Some(42.884065), Some(89.847252)),
List(Some(332.373186), Some(53.509768), Some(10.847252))
)
如何计算基本函数,例如:
对于每个列表的每个元素:
第一行
Some(301.873641) - Some(313.062468) / Some(313.062468)
Some(332.373186) - Some(301.873641) / Some(301.873641)
第二栏
Some(42.884065) - Some(27.847252) / Some(27.847252)
Some(53.509768) - Some(42.884065) / Some(42.884065)
第三栏
Some(89.847252) - Some(29.847252) / Some(29.847252)
Some(10.847252) - Some(89.847252) / Some(89.847252)
我目前卡在这里
data.map(_.head).foreach {
case i => println(i)
}
这只打印每个嵌套列表的头部。我不知道如何获取嵌套元素的每个元素并进行上述计算
结果应该是这样的:
List(
List(Some(-0.03573991820699504), Some(0.5399747522663995), Some(88.847252) )
List(Some(0.10103414428290529), Some(0.24777742035415723), Some(9.847252) )
)
您可能希望从使用 transpose
方法开始,并从那里开始您需要的逻辑。以下是对示例数据调用 transpose
的结果:
scala> data.transpose.foreach(println)
List(Some(313.062468), Some(301.873641), Some(332.373186))
List(Some(27.847252), Some(42.884065), Some(53.509768))
List(Some(29.847252), Some(89.847252), Some(10.847252))
转置、展平和压缩
val list = data.transpose.flatMap(_.flatten)
list.tail zip list map { case (a, b) => (b - a)/b }
scala> val list = data.transpose.flatMap(_.flatten)
list: List[Double] = List(313.062468, 301.873641, 332.373186, 27.847252, 42.884065, 53.509768, 29.847252, 89.847252, 10.847252)
Scala REPL
scala> list.tail zip list map { case (a, b) => (b - a)/b }
res19: List[Double] = List(0.03573991820699504, -0.10103414428290529, 0.9162169116734945, -0.5399747522663995, -0.24777742035415723, 0.4422092803691468, -2.010235314125401, 0.8792700749489812)
不是一个巧妙的解决方案,但有效
data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten.map { case (a, b) => (b - a)/b}
重要的代码行。
scala> data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten
res4: List[(Double, Double)] = List((313.062468,301.873641), (27.847252,42.884065), (29.847252,89.847252), (301.873641,332.373186), (42.884065,53.509768), (89.847252,10.847252))
scala> data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten.map { case (a, b) => (b - a)/b}
res5: List[Double] = List(-0.037064604126863805, 0.35063870460974256, 0.6678000569232768, 0.09176295286347183, 0.19857501531309202, -7.282950557431505)
Scala REPL
scala> var data = List(
| List(Some(313.062468), Some(27.847252), Some(29.847252)),
| List(Some(301.873641), Some(42.884065), Some(89.847252)),
| List(Some(332.373186), Some(53.509768), Some(10.847252))
| )
data: List[List[Some[Double]]] = List(List(Some(313.062468), Some(27.847252), Some(29.847252)), List(Some(301.873641), Some(42.884065), Some(89.847252)), List(Some(332.373186), Some(53.509768), Some(10.847252)))
scala> data.zip(data.tail)
res0: List[(List[Some[Double]], List[Some[Double]])] = List((List(Some(313.062468), Some(27.847252), Some(29.847252)),List(Some(301.873641), Some(42.884065), Some(89.847252))), (List(Some(301.873641), Some(42.884065), Some(89.847252)),List(Some(332.373186), Some(53.509768), Some(10.847252))))
scala> data.zip(data.tail).map { case (alist, blist) => alist zip blist }
res1: List[List[(Some[Double], Some[Double])]] = List(List((Some(313.062468),Some(301.873641)), (Some(27.847252),Some(42.884065)), (Some(29.847252),Some(89.847252))), List((Some(301.873641),Some(332.373186)), (Some(42.884065),Some(53.509768)), (Some(89.847252),Some(10.847252))))
scala> data.zip(data.tail).map { case (alist, blist) => alist zip blist }.flatten
res2: List[(Some[Double], Some[Double])] = List((Some(313.062468),Some(301.873641)), (Some(27.847252),Some(42.884065)), (Some(29.847252),Some(89.847252)), (Some(301.873641),Some(332.373186)), (Some(42.884065),Some(53.509768)), (Some(89.847252),Some(10.847252)))
scala> data.zip(data.tail).map { case (alist, blist) => alist zip blist }.flatten
res3: List[(Some[Double], Some[Double])] = List((Some(313.062468),Some(301.873641)), (Some(27.847252),Some(42.884065)), (Some(29.847252),Some(89.847252)), (Some(301.873641),Some(332.373186)), (Some(42.884065),Some(53.509768)), (Some(89.847252),Some(10.847252)))
scala> data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten
res4: List[(Double, Double)] = List((313.062468,301.873641), (27.847252,42.884065), (29.847252,89.847252), (301.873641,332.373186), (42.884065,53.509768), (89.847252,10.847252))
scala> data.zip(data.tail).map { case (alist, blist) => alist.flatten zip blist.flatten }.flatten.map { case (a, b) => (b - a)/b}
res5: List[Double] = List(-0.037064604126863805, 0.35063870460974256, 0.6678000569232768, 0.09176295286347183, 0.19857501531309202, -7.282950557431505)
转置列表,然后使用 .sliding(2)
获得元素的滚动 windows:
scala> def diffPercent(o1: Option[Double], o2: Option[Double]) = (o1, o2) match {
case (Some(d1), Some(d2)) => Some((d2 - d1) / d1) // need to handle d1 == 0 too
case _ => None
}
diffPercent: (o1: Option[Double], o2: Option[Double])Option[Double]
// sample value before the final operation
scala> data.transpose.map(_.sliding(2).toList) // .toList to show the values in REPL
res13: List[List[List[Some[Double]]]] = List(List(List(Some(313.062468), Some(301.873641)), List(Some(301.873641), Some(332.373186))), ...)
scala> data.transpose.map(_.sliding(2).map {
case o1 :: o2 :: Nil => diffPercent(o1, o2)
case _ => None // source has less than 2 elems
}.toList).transpose // transpose back the list
res17: List[List[Option[Double]]] = List(List(Some(-0.03573991820699504), Some(0.5399747522663995), Some(2.010235314125401)), List(Some(0.10103414428290529), Some(0.24777742035415723), Some(-0.8792700749489812)))
这个比其他的简单一点,没有使用transpose
。它非常接近@pamu 的。我从@Marth 的回答中借用了diffPercent
。
data.sliding(2)
.map{case List(a, b) => (a zip b).map {case (x,y) => diffPercent(x,y)}}
.toList