Kotlinで移動平均を計算するためのいくつかの汚い方法を考えることができますが、どれが最適かわかりません。kotlinには、コレクションやリストを操作するための興味深い機能がたくさんあることを私は知っています。移動平均を計算するための最も効率的な(または最も簡単な)方法は何だと思いますか?
Kotlin 1.2では、明らかに組み合わせることができるスライディングウィンドウが導入されますaverage
。
val data = listOf(1,2,5,6,2,7,8,5,9)
// 3 "period" moving average
val movingAverage = data.windowed(3,1,List<Int>::average)
// OR
val movingAverage = data.windowed(3,1) { it.average() }
それまでは、独自のスライドシーケンスを導入する必要があります。
class SlidingSequence<out T>(val source: Iterable<T>,
val slideSize: Int,
val slideStep: Int) : Sequence<List<T>> {
override fun iterator(): Iterator<List<T>> = object : AbstractIterator<List<T>>() {
private val iterator = if (slideSize > 0) source.iterator() else emptyList<T>().iterator()
private var buffer = listOf<T>()
override fun computeNext() = when {
iterator.hasNext() -> {
buffer = buffer.drop(slideStep).let {
it + iterator.asSequence().take(slideSize - it.size)
}
setNext(buffer)
}
else -> done()
}
}
}
fun <T> Iterable<T>.windowed(size: Int,
step: Int = 1): Sequence<List<T>> {
return SlidingSequence(this, size, step)
}
// and then you can do
val data = listOf(1,2,5,6,2,7,8,5,9)
// 3 "period" moving average
val movingAverage = data.windowed(3).map(List<Int>::average)
PS。Kotlin 1.2windowed
実装のコードを見ていませんが、関数はすぐに変換されるため、結果は怠惰ではないと思います。上記の自己実装の場合は怠惰な結果なので、実際に列挙する必要があります.toList()
実際の値を取得するようなものを持つシーケンス。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加