在 2 个 for 循环中使用 map 和 zip 使其更具功能性
Use map and zip to be more func style in 2 for loops
我实现了以下代码来使用 for 循环计算加权平均值,我怎样才能更 func 编程风格并使用 map
和 zip
?
val aggAvg = (emb: Seq[Seq[Float]], weights: Seq[Float]) => {
val embSize = emb.head.size
val len = emb.size
(0 until embSize)
.map { i =>
(0 until len).map { j =>
emb(j)(i) * weights(j)
}.sum / weights.sum
}
}
示例:
鉴于
val emb: Seq[Seq[Float]] = Seq(Seq(1,2,3), Seq(4,5,6))
val weights: Seq[Float] = Seq(2, 8)
输出将是 Seq(3.4, 4.4, 5.4)
因为
(1 * 2 + 4 * 8) / (2 + 8) = 3.4
等等。
这是一种方式,虽然我不确定它是否是最优雅的
val aggAvg = (emb: Seq[Seq[Float]], weights: Seq[Float]) =>
emb.transpose.map((weights, _).zipped.map(_ * _).sum).map(_ / weights.sum)
res0: Seq[Float] = List(3.4, 4.4, 5.4)
这使用 Iterator
代替 zip
操作。
val aggAvg = (emb: Seq[Seq[Float]], weights: Seq[Float]) => {
val wtItr = weights.iterator
val wtSum = weights.sum
emb.map(_.map(wtItr.next().*)).transpose.map(_.sum/wtSum)
}
注意:如果不是所有的行长度都与 weights
长度匹配,这可能会有点危险,但是您发布的 aggAvg
代码在这个守则中是相同的,所以我忽略了安全检查。
我实现了以下代码来使用 for 循环计算加权平均值,我怎样才能更 func 编程风格并使用 map
和 zip
?
val aggAvg = (emb: Seq[Seq[Float]], weights: Seq[Float]) => {
val embSize = emb.head.size
val len = emb.size
(0 until embSize)
.map { i =>
(0 until len).map { j =>
emb(j)(i) * weights(j)
}.sum / weights.sum
}
}
示例: 鉴于
val emb: Seq[Seq[Float]] = Seq(Seq(1,2,3), Seq(4,5,6))
val weights: Seq[Float] = Seq(2, 8)
输出将是 Seq(3.4, 4.4, 5.4)
因为
(1 * 2 + 4 * 8) / (2 + 8) = 3.4
等等。
这是一种方式,虽然我不确定它是否是最优雅的
val aggAvg = (emb: Seq[Seq[Float]], weights: Seq[Float]) =>
emb.transpose.map((weights, _).zipped.map(_ * _).sum).map(_ / weights.sum)
res0: Seq[Float] = List(3.4, 4.4, 5.4)
这使用 Iterator
代替 zip
操作。
val aggAvg = (emb: Seq[Seq[Float]], weights: Seq[Float]) => {
val wtItr = weights.iterator
val wtSum = weights.sum
emb.map(_.map(wtItr.next().*)).transpose.map(_.sum/wtSum)
}
注意:如果不是所有的行长度都与 weights
长度匹配,这可能会有点危险,但是您发布的 aggAvg
代码在这个守则中是相同的,所以我忽略了安全检查。