平滑数组并保持Scala中的数组长度不变

时间:2018-02-27 23:33:14

标签: scala

我有一个像这样的数组平滑函数:

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)  

或者更好的方法,如果有人能提出来吗?

1 个答案:

答案 0 :(得分:2)

您没有指定如何处理边界条件。 从您的示例中我推断出您希望将值保留在边界上 已修复(114保持不变)。

这是一个平滑操作,可以生成相同大小和保留的数组 边界条件:

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














                                                                         #######
                                                             ###################
                                                 ###############################
                                     ###########################################
                        ########################################################
            ####################################################################

希望有所帮助。