Reduce data by taking averages

I am trying to implement the following:

I have got two vectors x and y of unequal lengths. The length of y is much larger than x.

I want to define a new y such that its length will be equal to the length of x by taking appropriate averages of the elements in y. For example, if y includes 200 elements and x 100 elements, then I would define a new y such that y will be the average of every subsequent two elements in y.

-

Assuming that the lengths of the lists are integer multiples of each other, you could do this:

x = RandomInteger[{0, 100}, 100];
y = RandomInteger[{0, 100}, 200];

Mean /@ Partition[y, Length[y]/Length[x]]

(*
==> {37/2, 79, 23, 58, 111/2, 59, 143/2, 45/2, 51, 123/2, 57, \
76, 43, 111/2, 93/2, 33, 97/2, 37/2, 51, 151/2, 43, 7/2, 191/2, \
123/2, 44, 49, 68, 129/2, 137/2, 121/2, 99/2, 85/2, 81/2, 77/2, 73, \
179/2, 129/2, 36, 51, 135/2, 95/2, 63, 71, 31, 91, 36, 49, 43/2, 80, \
23, 51, 123/2, 59, 54, 37, 123/2, 57, 81/2, 115/2, 123/2, 121/2, \
103/2, 129/2, 39, 91/2, 46, 85, 53/2, 43/2, 83, 71, 24, 27, 66, 47/2, \
52, 113/2, 97/2, 57/2, 71, 68, 48, 22, 129/2, 103/2, 141/2, 45/2, \
123/2, 30, 131/2, 45, 83, 74, 18, 79/2, 115/2, 29, 113/2, 59, 66}
*)


If the lengths aren't divisible, you can do this:

With[{n = Floor[Length[y]/Length[x]]},
Mean /@ Partition[PadRight[y, n Length[x], Last[y]], n]]


which adjusts the size of y before partitioning it.

Above, you can replace Floor by Ceiling or Round, depending on how you want to handle cases where the lengths are mismatched. The PadRight doesn't have to be changed, though. If the partitioned list is too short, it will cut off the right-most element(s), otherwise it will add the last element until the desired length is reached.

Following rcollyer's comment, one could also do something like this:

Needs["Developer"]

With[{n = Floor[Length[y]/Length[x]]},
PartitionMap[Mean, PadRight[y, n Length[x], Last[y]], n]]


This combines two steps of my first approach into one command, PartitionMap.

-
You might be better off with Ceiling[Length[y]/Length[x]]] rather than Floor[ ], because if you end up with 0 length in the Partition, you will get an error. – bill s Apr 5 '13 at 7:11
I'd use DeveloperPartitionMap for this, as it applies the function as it is partitioning the list. It tends to be a bit faster. The signature is DeveloperPartitionMap[f_, partitionargs__]. – rcollyer Apr 5 '13 at 12:48
@rcollyer Thanks for the alternative - it's documented under the Developer package, but it was new to me. – Jens Apr 5 '13 at 16:00
Since at least v8 (maybe in v7, too), Developer  has been accessible without resorting to Needs, but only by fully qualifying the name. So, Needs here puts Developer  onto the \$ContextPath, but nothing more. :) – rcollyer Apr 5 '13 at 16:41
@rcollyer Neat, Needs ain't needed... – Jens Apr 5 '13 at 16:47

As I interpret the question I recommend that you use Interpolation for this due to its versatility and configurability.

Here is some example data:

x = Table[Sin[x], {x, 0, 7 Pi, 7 Pi/99}];
y = Table[Cos[x], {x, 0, 7 Pi, 7 Pi/236}];
{lnx, lny} = Length /@ {x, y}


{100, 237}

Now create a mapping and plot it:

yint = Interpolation[y, InterpolationOrder -> 1];

y2 = yint @ Rescale[Range@lnx, {1, lnx}, {1, lny}];

ListLinePlot[{x, y2}]
`

-