1
votes

I have a vector x containing velocity information and the index represents time. Now I wish to create a new vector, preserving its size, but values are replaced with mean of a time interval eg:

x = 
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112

if i want to time interval to be 4, the output should look like:

o = 
102.5
102.5
102.5
102.5
106.5
106.5
106.5
106.5
110.5
110.5
110.5
110.5

Is there a function that does that? thanks

2
This reads like you want a moving average. Is that correct? - PengOne
I think I didn't fully understand what you're trying to achieve, but you may want to take a look at smooth. - Adiel Mittmann
Yes, moving average is what I was looking for! is there a built in function that does that? also I tried smooth, it doesn't smooth it very much, i am guessing it's because my graph is too 'noisy', only finding the average can reduce the noise. - Bonk
Actually, I take it back. its not not exactly moving average. I want to find one average per year. Instead of "smoothing" the graph. The graph should look more like a step function than a smoothed curve function. - Bonk

2 Answers

1
votes

Here's a method that doesn't require that your time vector is an exact multiple of the interval length that combines accumarray with some clever indexing.

x = [101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112];

intervalLength = 4;

%# create index array
%# for array of length 10, 
%# intervalLength 4, this gives
%# [1 1 1 1 2 2 2 2 3 3]'
idx = zeros(length(x),1);
idx(1:intervalLength:end) = 1;
idx = cumsum(idx);

%# average time
avg = accumarray(idx,x,[],@mean);

%# create output array - use index to replicate values
out = avg(idx);

out =
    102.5
    102.5
    102.5
    102.5
    106.5
    106.5
    106.5
    106.5
    110.5
    110.5
    110.5
    110.5
0
votes

It appears that you're trying to perform a stepping average across the input data set, while preserving the length of the initial input vector. To my knowledge, there is no single function to do this.

However, you can do it in Python fairly easily. For example:

def blurryAverage(inputCollection, step=1):
    """ Perform a tiling average of an input data set according to its 
     step length, preserving the length of the initial input vector """

    # Preconditions
    if (len(inputCollection) % step != 0):
        raise ValueError('Input data must be of divisible length')

    ret = []
    for i in range(len(inputCollection) / step):
        tot = 0.0
        for j in range(step):
            tot += inputCollection[(i*step)+j]

        for j in range(step):
            ret.append(tot / step) # Implicit float coercion of step

    return ret


>>> blurryAverage([1,2,3,4,5,6],3)
[2.0, 2.0, 2.0, 5.0, 5.0, 5.0]

>>> blurryAverage([1,2,3],4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in blurryAverage
ValueError: Input data must be of divisible length