Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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
share|improve this question
    
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? –  J. M. May 14 '12 at 13:06
1  
I have no problem with closing this one –  mmorris May 14 '12 at 15:06
show 1 more comment

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

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

4 Answers

up vote 8 down vote accepted

There is a function exactly for this: Developer`PartitionMap:

Developer`PartitionMap[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 Developer`PartitionMap is the function that's being used (f) and all successive arguments and options are exactly the same as in Partition.

share|improve this answer
    
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[Developer`PartitionMap[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.. –  rm -rf 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
show 1 more comment

You can try

MovingAverage[Range[1,10],3]
share|improve this answer
1  
His use of Mean was just an example... –  rm -rf 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
add comment

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}
share|improve this answer
add comment

Why not just

slide3[f_, expr_, n_Integer] :=   f /@ Partition[expr, n, 1];
share|improve this answer
    
Exactly, why not! ;) I was unaware of the the offset. Cool thanks! –  mmorris May 11 '12 at 20:39
2  
@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 Developer`PartitionMap[f, expr, n, 1] which tends to be faster. –  rcollyer May 13 '12 at 1:58
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.