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.

I am trying to take averages of a large two dimensional array at certain intervals. For example, for the first row, I want to take K averages of 500 values.

Here is what I am trying

Do[Data[[i, k]] = 
Mean[Data[[i]][[j + 1 ;; j + 500, 2 ]] ], {i, 
8}, {j, 0, 
100*5*200, 500}, {k, 1,
200} ]*)
share|improve this question
    
Oh, I think I am redefining my matrix and using the redefined values again in all calculations. –  l3win Jul 8 '13 at 2:07
    
You are right, redefining your matrix this way is inefficient and can lead to unexpected results. Have a look at MovingAverage in the documentation and see if that does what you need. –  Verbeia Jul 8 '13 at 2:29
    
MovingAverage doesn't take all the elements I average over and reduce them to a single value, I think. –  l3win Jul 8 '13 at 2:32
    
I see now what you are trying to do. Have a look at Partition. Mean/@ Partition[data,500] should do what you want for a vector, I think. For a 2D matrix, if what you want is a list of vectors where each vector captures the (non-overlapping) averages of 500-element sublists of each row of the original matrix, then you need: (Mean/@Partition[#,500])/@ data. –  Verbeia Jul 8 '13 at 3:36

2 Answers 2

Your code doesn't make sense to me. Not only are you redefining values in Data mid-process, as you note, your are also extracting elements down to the third level (Data[[i]][[j + 1 ;; j + 500, 2 ]]) yet you say this is a "two dimensional array."

I shall assume that you want to average all elements in an m by n window, either with or without overlap. Using this data as an example:

a = CharacterRange["a", "p"] ~Partition~ 4;
a // MatrixForm

$\left( \begin{array}{cccc} a & b & c & d \\ e & f & g & h \\ i & j & k & l \\ m & n & o & p \end{array} \right)$

If you want to take the mean of the following $2 \times 3$ groups:

Partition[a, {2, 3}, 1] // MatrixForm

$\left( \begin{array}{cc} \left( \begin{array}{ccc} a & b & c \\ e & f & g \end{array} \right) & \left( \begin{array}{ccc} b & c & d \\ f & g & h \end{array} \right) \\ \left( \begin{array}{ccc} e & f & g \\ i & j & k \end{array} \right) & \left( \begin{array}{ccc} f & g & h \\ j & k & l \end{array} \right) \\ \left( \begin{array}{ccc} i & j & k \\ m & n & o \end{array} \right) & \left( \begin{array}{ccc} j & k & l \\ n & o & p \end{array} \right) \end{array} \right)$

You could use:

Needs["Developer`"]

PartitionMap[Mean @ Flatten @ # &, a, {2, 3}, 1]

$\left( \begin{array}{cc} \frac{1}{6} (a+b+c+e+f+g) & \frac{1}{6} (b+c+d+f+g+h) \\ \frac{1}{6} (e+f+g+i+j+k) & \frac{1}{6} (f+g+h+j+k+l) \\ \frac{1}{6} (i+j+k+m+n+o) & \frac{1}{6} (j+k+l+n+o+p) \end{array} \right)$

Partition and PartitionMap have the advantage of being flexible and easy to observe, but they are also inefficient for this. (PartitionMap is more memory efficient than Partition, but both end up adding and dividing the same elements many times.)

You can more efficiently perform this particular operation (offsets of one) using MovingAverage once in each direction:

Fold[MovingAverage[#\[Transpose], #2] &, a, {3, 2}] // Factor // MatrixForm

$\left( \begin{array}{cc} \frac{1}{6} (a+b+c+e+f+g) & \frac{1}{6} (b+c+d+f+g+h) \\ \frac{1}{6} (e+f+g+i+j+k) & \frac{1}{6} (f+g+h+j+k+l) \\ \frac{1}{6} (i+j+k+m+n+o) & \frac{1}{6} (j+k+l+n+o+p) \end{array} \right)$

Still more efficient is ListCorrelate, though it is perhaps bit less intuitive:

ListCorrelate[ConstantArray[1/6, {2, 3}], a] // Factor // MatrixForm

$\left( \begin{array}{cc} \frac{1}{6} (a+b+c+e+f+g) & \frac{1}{6} (b+c+d+f+g+h) \\ \frac{1}{6} (e+f+g+i+j+k) & \frac{1}{6} (f+g+h+j+k+l) \\ \frac{1}{6} (i+j+k+m+n+o) & \frac{1}{6} (j+k+l+n+o+p) \end{array} \right)$

For different offsets PartitionMap is the simplest method I know of:

PartitionMap[Mean@Flatten@# &, a, {2, 2}] // MatrixForm

$\left( \begin{array}{cc} \frac{1}{4} (a+b+e+f) & \frac{1}{4} (c+d+g+h) \\ \frac{1}{4} (i+j+m+n) & \frac{1}{4} (k+l+o+p) \end{array} \right)$

PartitionMap[Mean@Flatten@# &, a, {2, 3}, {2, 1}] // MatrixForm

$\left( \begin{array}{cc} \frac{1}{6} (a+b+c+e+f+g) & \frac{1}{6} (b+c+d+f+g+h) \\ \frac{1}{6} (i+j+k+m+n+o) & \frac{1}{6} (j+k+l+n+o+p) \end{array} \right)$

PartitionMap[Mean@Flatten@# &, a, {3, 2}, {1, 2}, {-1, 1}, {}] // MatrixForm

$\left( \begin{array}{ccc} a & \frac{b+c}{2} & d \\ \frac{a+e}{2} & \frac{1}{4} (b+c+f+g) & \frac{d+h}{2} \\ \frac{1}{3} (a+e+i) & \frac{1}{6} (b+c+f+g+j+k) & \frac{1}{3} (d+h+l) \\ \frac{1}{3} (e+i+m) & \frac{1}{6} (f+g+j+k+n+o) & \frac{1}{3} (h+l+p) \\ \frac{i+m}{2} & \frac{1}{4} (j+k+n+o) & \frac{l+p}{2} \\ m & \frac{n+o}{2} & p \end{array} \right)$

share|improve this answer

There is also a built-in version of the 2D moving average filter called MeanFilter. It couldn't be simpler to use:

MeanFilter[data,2]

filters the data in the matrix by replacing every value by the mean value in its range-2 neighborhood. You can be more specific about how you want to filter by specifying {x,y} sizes separately:

MeanFilter[a, {2, 30}]

More general filters with different sizes and shape kernels can be accomplished using ListConvolve and/or `ListCorrelate'.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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