我有一个像这样的数组平滑函数:
def smoothArray(rawdata:Array[Double], window:Int):Array[Double] = {
rawdata.sliding(window).map(_.sum/window).toArray
}
但是,输出数组大小与输入数组大小不同。这是因为滑动函数仅生成window
大小的组。
无论如何输出与输入相同大小的数组?甚至使用相同的数据点?例如,对于
val input = Array(1,2,4,9,14)
val window = 3
输出如下:
(1, 2.33, 5, 9, 14)
或者更好的方法,如果有人能提出来吗?
答案 0 :(得分:2)
您没有指定如何处理边界条件。
从您的示例中我推断出您希望将值保留在边界上
已修复(1
和14
保持不变)。
这是一个平滑操作,可以生成相同大小和保留的数组 边界条件:
def smoothArray(rawdata:Array[Double], window:Int):Array[Double] = {
require(window % 2 == 1, "The kernel should be symmetrical, only windows of uneven size allowed")
val leftBoundary = rawdata.head
val rightBoundary = rawdata.last
val truncatedHalfKernelWidth = window / 2 // must be integer division!
val leftPadding = Array.fill(truncatedHalfKernelWidth)(leftBoundary)
val rightPadding = Array.fill(truncatedHalfKernelWidth)(rightBoundary)
val res = (leftPadding ++ rawdata ++ rightPadding).sliding(window).map(_.sum/window).toArray
// restoring the boundary conditions
res(0) = leftBoundary
res(res.size - 1) = rightBoundary
res
}
以下是您的示例:
/* first tiny example */ {
val input = Array[Double](1,2,4,9,14)
println(smoothArray(input, 3).map(x => "%1.2f".format(x)).mkString(","))
println(smoothArray(input, 5).map(x => "%1.2f".format(x)).mkString(","))
println(smoothArray(input, 7).map(x => "%1.2f".format(x)).mkString(","))
}
以下是您的示例的输出:
1.00,2.33,5.00,9.00,14.00 // w = 3
1.00,3.40,6.00,8.60,14.00 // w = 5
1.00,4.57,6.43,8.29,14.00 // w = 7
这种平滑操作的有趣之处在于它可以解决热量方程式 迭代几次。这是一个扩展示例,其中包含更大的数组,更有趣 初始值(原谅我丑陋的ascii图形,从控制台运行):
/* More interesting iterative example */ {
def drawArray(arr: Array[Double], yRange: Range): Unit = {
val width = arr.size
val visibleHeight = 20
val canvas = Array.fill(visibleHeight, width)(' ')
for (i <- 0 until width) {
val y = arr(i)
val barHeight = (visibleHeight * (y - yRange.min) / yRange.size).toInt
if (barHeight > 0) {
for (j <- 0 until (barHeight min visibleHeight)) {
canvas(visibleHeight - j - 1)(i) = '#'
}
}
}
for (row <- canvas) println(row.mkString)
}
val initialArray = Array.tabulate(80){ x =>
val linearTerm = x * 1000 / 80
val parabolicTerm = x * (79 - x)
val sineTerm = math.sin(x / 80.0 * math.Pi * 4)
val randomTerm = math.random * 1000
linearTerm + (if (x != 0 && x != 79) {
parabolicTerm + sineTerm + randomTerm
} else 0.0)
}
var smoothed = initialArray
for (iter <- 0 until 10000) {
if (iter < 10 || (iter < 2000 && iter % 100 == 0) || iter % 1000 == 0) {
println("iter " + iter)
drawArray(smoothed, 0 to 3000)
}
smoothed = smoothArray(smoothed, 5)
}
}
首先是
的混合-
iter 0
# # # #
# ### # ## # # # #
# ### # ### # # ## #
# # ### # ##### ## ### ### # ##
# # ## ############### ###### ### # ## #
# # # ### ############################ ##### #
# # # ## ################################ ##### ## #
# # # ############################################ ## # #
## #### ########################################################
### #### #########################################################
#### ##############################################################
# ####################################################################
# #######################################################################
# #########################################################################
###########################################################################
# ############################################################################
# #############################################################################
# #############################################################################
###############################################################################
在几次迭代中,它会杀死高频噪声:
iter 1
# #
###########
################# #####
#####################################
######################################
########################################### #
## # ####################################################
###############################################################
##################################################################
###################################################################
#####################################################################
########################################################################
##########################################################################
###########################################################################
#############################################################################
#############################################################################
###############################################################################
###############################################################################
iter 5
##########
########################
##################################
#######################################
#############################################
####################################################
############################################################
###############################################################
##################################################################
#####################################################################
#######################################################################
#########################################################################
###########################################################################
############################################################################
#############################################################################
##############################################################################
###############################################################################
然后它大部分平滑了正弦振荡,直到我们留下了一个 抛物线凸起的压扁版本:
iter 200
#######
########################
##################################
########################################
###############################################
#####################################################
###########################################################
################################################################
###################################################################
######################################################################
########################################################################
##########################################################################
############################################################################
##############################################################################
抛物线术语变得越来越小......
iter 700
############################
##############################################
#######################################################
############################################################
#################################################################
#####################################################################
########################################################################
############################################################################
直到所有东西完全“平滑”成两者之间的直线 边界条件:
iter 9000
#######
###################
###############################
###########################################
########################################################
####################################################################
希望有所帮助。