我在工作区中创建了这个变量:
z=
0.000894000000000000
-0.000929000000000000
0.00101500000000000
0.000747000000000000
0.00103900000000000
0.000888000000000000
0.000828000000000000
0.000737000000000000
0.000858000000000000
-0.000723000000000000
0.000874000000000000
我想用直接在这个数字的上方和下方找到的数字的平均值来编写代替负数的代码。
答案 0 :(得分:4)
不是最有效的方法,但是......
av = conv(z, [.5 0 .5], 'same'); %// compute average for all elements
ind = z<0; %// determine which are negative
z(ind) = av(ind); %// replace those only
答案 1 :(得分:3)
您可以通过线性插值方法来处理此问题。假设z
中没有连续的负数,您可以使用interp1
执行此操作:
%// 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');
这也处理了开头和结尾都有负值的情况,而extrap
标志只是外推。如果开头和结尾的值都是负面的,我不确定这是否是你想要的,但我会留下让你弄清楚。
尽管如此,这种方法背后的美妙之处在于我们提供的控制点从1到z
中的多个点被描绘出来。这些是x
点。输出y
点是z
中的值。但是,我们删除了那些负面的控制点 - 与z
相同。
接下来,我们在z
中指定从1到最多元素的全部关键点,以实现最终输出。在这种情况下,使用线性插值可以有效地找到由负数分隔的两个点之间的平均值。
然而,如果有连续的负数,那么我们将看到在负值链开始之前的积极价值,并观察链后的正值,以及连续数字的运行,值被平滑插值。我不确定这是不是你想要的,所以我会留在这里让你弄明白。
这是我们获得的输出:
>> 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
或者,您可以使用find
,但请遵循以下假设:
此代码适用于以下假设:
z
在开头和结尾都没有负数z
中没有连续的负数。因此:
%// 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;
上面的代码会改变z
,以便将负值替换为邻近的平均值。我们再次得到:
>> 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
答案 2 :(得分:0)
试试这个:
for index = 1 : length( z )
if ( z( index ) < 0 ) // FIXED
above = max( index, 1 );
below = min( index, length( z ) );
z( index ) = mean( z( above ), z( below ) ); // FIXED
end
end
但这不完全正确。在以下情况下会发生什么: