code: def moving_average(a, length, mode='valid'):
      
      pad = np.floor(length/2)
  
      if mode == 'full':
          pad *= 2
      pad = int(pad)
  
      # Make a padded version, paddding with first and last values
      r = np.zeros(a.shape[0] + 2*pad)
      r[:pad] = a[0]
      r[pad:-pad] = a
      r[-pad:] = a[-1]
  
      # Cumsum with shifting trick
      s = np.cumsum(r, dtype=float)
      s[length:] = s[length:] - s[:-length]
      out = s[length-1:]/length
  
      # Decide what to return
      if mode == 'same':
          if out.shape[0] != a.shape[0]:
              # If size doesn't match, then interpolate.
              out = (out[:-1, ...] + out[1:, ...]) / 2
          return out
      elif mode == 'valid':
          return out[pad:-pad]
      else:  # mode=='full' and we used a double pad
          return out
docs: From ``bruges``
  
      Computes the mean in a moving window. Naive implementation.
  
      Example:
          >>> test = np.array([1,9,9,9,9,9,9,2,3,9,2,2,3,1,1,1,1,3,4,9,9,9,8,3])
          >>> moving_average(test, 7, mode='same')
          [ 4.42857143,  5.57142857,  6.71428571,  7.85714286,  8.        ,
          7.14285714,  7.14285714,  6.14285714,  5.14285714,  4.28571429,
          3.14285714,  3.        ,  2.71428571,  1.57142857,  1.71428571,
          2.        ,  2.85714286,  4.        ,  5.14285714,  6.14285714,
          6.42857143,  6.42857143,  6.28571429,  5.42857143]
  
      TODO:
          Other types of average.