# 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

-

## marked as duplicate by Mr.Wizard♦Aug 10 '12 at 23:24

I think this is a duplicate of: mathematica.stackexchange.com/q/4061/121 (Admittedly better written, but still a duplicate.) –  Mr.Wizard May 11 '12 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. –  mmorris May 11 '12 at 21:46
mmorris, is it OK with you if I close this question? –  Mr.Wizard May 11 '12 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? –  Guess who it is. May 14 '12 at 13:06
I have no problem with closing this one –  mmorris May 14 '12 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. –  Sjoerd C. de Vries May 11 '12 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 –  mmorris May 11 '12 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.. –  The Toad May 11 '12 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. –  Sjoerd C. de Vries May 11 '12 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. –  rcollyer May 26 '12 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! –  mmorris May 11 '12 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. –  Leonid Shifrin May 11 '12 at 20:40
Agreed! Sorry need to wait longer to assign check. –  mmorris May 11 '12 at 20:48
Better yet, use DeveloperPartitionMap[f, expr, n, 1] which tends to be faster. –  rcollyer May 13 '12 at 1:58

You can try

MovingAverage[Range[1,10],3]

-
His use of Mean` was just an example... –  The Toad May 11 '12 at 20:33
While this works for the given example, it does not answer the question. –  mmorris May 11 '12 at 20:55