哈斯克尔的移动平均线 [英] Moving average in Haskell

查看:117
本文介绍了哈斯克尔的移动平均线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出权重列表:

let weights = [0.1, 0.2, 0.4, 0.2, 0.1]

和一系列测量值,我想实现加权平均值.

and an array of measurements, I want to implement the weighted average.

这就是我要在Python中执行的操作:

This is how I would do it in Python:

y=[]
w = length(weights)
for n in range(w,len(x)-w):
    y[n-w/2-1]=sum([a*b for a,b in zip(weights,x[n-w/2:n+w/2+1])])
    #y[n-3]=W[1]*x[n-2]+W[2]*x[n-1]+W[3]*x[n]+W[4]*x[n+1]+W[5]*x[n+2]

我知道Haskell没有数组,我想要实现的是低-pass-filter ,我可以在其中手动定义权重.

I know Haskell doesn't have arrays, what I'm trying to achieve is a low-pass-filter, in which I can define the weights manually.

推荐答案

tails 为您提供输入列表尾部的列表.因此 tails [1,2,3] = [[1,2,3],[2,3],[3],[]] .由于我们不需要最后一个空列表,因此我们使用(init.tails)将除最后一个元素之外的所有内容都添加到尾部列表中.

tails gives you a list of the tails of the input list. So tails [1,2,3] = [[1,2,3],[2,3],[3],[]]. Since we don't need the last empty list we use (init.tails) to get everything in the tails list except the last element.

import Data.List (tails)
averages :: Num a => [a] -> [a] -> [a]
averages weights xs = sum . zipWith (*) weights <$> (init.tails) xs

请注意,这很可能在列表的开头和结尾都没有您想要的方式.特别是因为它在开始时和结束时的行为不同.第一个元素是第一个 length weight 元素的平均值,但最后一个元素仅是 head weight * last xs .

Note that this very likely doesn't behave the way you want at the start and end of the list. Especially because it behaves different at the start then at the end. The first element will be the average of the first length weight element, but the last element will only be head weight * last xs.

如果您希望一开始就表现出结束的行为,则可以使用类似以下的内容:

If you want the behaviour of the end at the start you can use something like this:

import Data.List (tails)
averages :: Num a => [a] -> [a] -> [a]
averages weights xs = sum . zipWith (*) weights <$>
  (init.tails) (replicate (length weights - 1) 0 ++ xs)

如果您希望一开始就表现出结束的行为,可以使用以下方法:

If you want the behaviour of the end at the start you can use this:

import Data.List (tails)
averages :: Num a => [a] -> [a] -> [a]
averages weights xs = sum . zipWith (*) weights <$>
  takeWhile (not . null . drop (l-1)) (tails xs)
  where l = length weights

如果要开始和结束时将第一个/最后一个元素与权重列表的中心元素相乘,我们必须使用以上两个答案的组合:

If you want to start and end with the first/last element being multiplied with the center element of the weights list we have to use a combination of the two above answers:

import Data.List (tails)
averages :: Num a => [a] -> [a] -> [a]
averages weights xs = sum . zipWith (*) weights <$>
  takeWhile (not . null . drop half) (replicate half 0 ++ xs)
  where half = length weights `quot` 2

这篇关于哈斯克尔的移动平均线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆