# Evaluating a function using arguments from a sliding window over a list [duplicate]

Possible Duplicate:
How to Map a subset of list elements to a function?

I want to evaluate a function using arguments from a sliding window over a list.

As an example, lets use Mean as the function, window size as 3, and the list as Range[1, 10].

The results I am looking for are:

{ Mean[{1,2,3}], Mean[{2,3,4}], ... Mean[{8,9,10}] }


i.e.

{2, 3, 4, 5, 6, 7, 8, 9}


Is there something in Mathematica that can do this, or an improvement on the following implementations?

## Implementation #1

Slide1[f_, expr_, n_Integer] :=
Module[{myExpr},
myExpr = RotateRight[expr, 1];
Nest[
Delete[#, -1] &,
Map[(
myExpr = RotateLeft[myExpr, 1];
f[myExpr[[1 ;; n]]]
) &, myExpr],
n - 1]
];

In[]:=  Slide1[Mean, Range[1, 10], 3]
Out[]:= {2, 3, 4, 5, 6, 7, 8, 9}


Rotating can not be that efficient, can it?

In[]:=  AbsoluteTiming[Slide1[Mean, Range[1, 100000], 3]][[1]]
Out[]:= 3.529240


## Implementation #2

Slide2[f_, expr_, n_Integer] :=
Module[{result, i},
result = {};
For[i = 1, i <= Length[expr] - n + 1, i++,
AppendTo[result, f[expr[[i ;; i + n - 1]]]];
];
result
]

In[]:=  Slide2[Mean, Range[1, 10], 3]
Out[]:= {2, 3, 4, 5, 6, 7, 8, 9}


Please ... For and AppendTo

In[]:=  AbsoluteTiming[Slide2[Mean, Range[1, 100000], 3]][[1]]
Out[]:= 27.811511

• I think this is a duplicate of: mathematica.stackexchange.com/q/4061/121 (Admittedly better written, but still a duplicate.) May 11, 2012 at 21:29
• I concur (the part about being a duplicate question). A "subset", "sliding window over a list", or in Mathematica speak, a "sublist" are the same thing. Just did not show up in my query. May 11, 2012 at 21:46
• mmorris, is it OK with you if I close this question? May 11, 2012 at 21:48
• @Mr.Wizard: I like this question better, since OP showed some legwork, making this a better example of questions we'd like to see. How about closing the older one as a dupe of this instead? May 14, 2012 at 13:06
• I have no problem with closing this one May 14, 2012 at 15:06

There is a function exactly for this: DeveloperPartitionMap:

DeveloperPartitionMap[f, {1, 2, 3, 4, 5, 6}, 3, 1]
(* {f[{1, 2, 3}], f[{2, 3, 4}], f[{3, 4, 5}], f[{4, 5, 6}]} *)


The first argument to DeveloperPartitionMap is the function that's being used (f) and all successive arguments and options are exactly the same as in Partition.

• PartitionMap is reportedly slow. May 11, 2012 at 20:44
• AbsoluteTiming[Slide1[Mean, Range[1, 100000], 3]][[1]] ==> 3.487248 AbsoluteTiming[slide3[Mean, Range[1, 100000], 3]][[1]] ==> 0.119232 AbsoluteTiming[DeveloperPartitionMap[Mean, Range[1, 100000], 3, 1]][[1]] ==> 0.088112 May 11, 2012 at 20:45
• @SjoerdC.deVries Don't see that in this case. Could be due to the use of @@ in your linked question, but someone else might be more qualified to answer that..
– rm -rf
May 11, 2012 at 20:53
• On my PC I get about the same performance for Partition and PartitionMap in this situation. The link suffices to help us remember we shouldn't generalize from one data point. May 11, 2012 at 21:00
• @SjoerdC.deVries PartitionMap will leave a list packed, provided that you don't do something to unpack it, like use Apply. Generally, I've found it quite fast. May 26, 2012 at 1:57

For something more general.

movingMap[f_, data_, r_] :=
ListConvolve[ConstantArray[1, r], data, {-1, 1}, {}, Times, f@{##} &]

movingMap[Mean, Range[10], 3]

==> {2, 3, 4, 5, 6, 7, 8, 9}


Why not just

slide3[f_, expr_, n_Integer] :=   f /@ Partition[expr, n, 1];

• Exactly, why not! ;) I was unaware of the the offset. Cool thanks! May 11, 2012 at 20:39
• @mmorris Thanks for accepting, but I think the answer of R.M. is superior, so I'd recommend to accept that answer instead. May 11, 2012 at 20:40
• Agreed! Sorry need to wait longer to assign check. May 11, 2012 at 20:48
• Better yet, use DeveloperPartitionMap[f, expr, n, 1] which tends to be faster. May 13, 2012 at 1:58

You can try

MovingAverage[Range[1,10],3]

• His use of Mean` was just an example...
– rm -rf
May 11, 2012 at 20:33
• While this works for the given example, it does not answer the question. May 11, 2012 at 20:55