Get notified about new tutorials
RECEIVE NEW TUTORIALS

First 15 Minutes Free

310 sessions given

since Jul 09, 2014

since Jul 09, 2014

Likelihood of Reply:
95%

Response Time:
within an hour

Ray Phan

Jun 24, 2015

<p>You can approach this in a linear interpolation viewpoint. Assuming that there are no consecutive negative numbers in <code>z</code>, you can do this with <a href="http://www.mathworks.com/help/matlab/ref/interp1.html" rel="nofollow"><code>interp1</code></a>:</p>
<pre><code>%// Define your data
z= [...
0.000894000000000000
-0.000929000000000000
0.00101500000000000
0.000747000000000000
0.00103900000000000
0.000888000000000000
0.000828000000000000
0.000737000000000000
0.000858000000000000
-0.000723000000000000
0.000874000000000000];
keys = (1 : numel(z)).';
out = interp1(keys(z >= 0), z(z >= 0), keys, 'linear', 'extrap');
</code></pre>
<p>This also handles the case where there are negative values at the beginning and at the end, and the <code>extrap</code> flag simply extrapolates. I'm not sure if this is what you intended if there are values at the beginning and end that are negative, but I'll leave that for you to figure out.</p>
<p>Nevertheless, the beauty behind this approach is that we provide control points that are delineated from 1 up to as many points in <code>z</code> that we have. These are the <code>x</code> points. The output <code>y</code> points are the values in <code>z</code>. However, we remove those control points that are negative - the same is done for <code>z</code>.</p>
<p>Next, we specify the full spectrum of key points from 1 up to as many elements in <code>z</code> to achieve the final output. Using linear interpolation in this case effectively finds the average between the two points that are separated by a negative.</p>
<p>However, should there be consecutive negative numbers, then what will happen is that we take a look at the value that was positive before the chain of negative values began and look at the value that was positive after the chain, and in between the run of consecutive numbers, the values are smoothly interpolated. I'm not sure if this is what you want, so I'll leave that here for you to figure out.</p>
<p>This is the output we get:</p>
<pre><code>>> format long g;
>> out
out =
0.000894
0.0009545
0.001015
0.000747
0.001039
0.000888
0.000828
0.000737
0.000858
0.000866
0.000874
</code></pre>
<hr>
<p>Alternatively, you can use <a href="http://www.mathworks.com/help/matlab/ref/find.html" rel="nofollow"><code>find</code></a>, but under the following assumptions:</p>
<p>This code works with the following assumptions:</p>
<ol>
<li><code>z</code> does not have a negative number at the start and at the end</li>
<li>There are no consecutive negative numbers in <code>z</code>.</li>
</ol>
<p>Therefore:</p>
<pre><code>%// Find negative values in z
ind = find(z < 0);
%// Replace each negative value with the
%// average of the values above and below each negative
z(ind) = (z(ind-1) + z(ind+1)) / 2;
</code></pre>
<p>The above code mutates <code>z</code> so that the negative values are replaced by the neighbouring average. We again get:</p>
<pre><code>>> format long g;
>> z
z =
0.000894
0.0009545
0.001015
0.000747
0.001039
0.000888
0.000828
0.000737
0.000858
0.000866
0.000874
</code></pre>
<p>This tip was originally posted on <a href="http://stackoverflow.com/questions/30900837/Replace%20part%20of%20an%20array%20with%20the%20average%20of%20its%20neighbors/30901348">Stack Overflow</a>.</p>