哈斯克尔的移动平均线 [英] Moving average in Haskell
问题描述
给出权重列表:
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屋!