【问题标题】:Replace part of an array with the average of its neighbors将数组的一部分替换为其邻居的平均值
【发布时间】:2015-06-17 19:36:54
【问题描述】:

我在工作区中创建了这个变量:

z=

0.000894000000000000

-0.000929000000000000

0.00101500000000000

0.000747000000000000

0.00103900000000000

0.000888000000000000

0.000828000000000000

0.000737000000000000

0.000858000000000000

-0.000723000000000000

0.000874000000000000

我想编写代码,将负数替换为在该数字正上方和下方找到的数字的平均值。

【问题讨论】:

  • 连续出现多个负数的情况如何处理?
  • 另外,如果第一个元素和/或最后一个元素为负数会怎样?
  • 那么交易是什么?我们有人回答了你的问题吗?

标签: arrays matlab average


【解决方案1】:

不是最有效的方法,但是...

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

【讨论】:

  • 仍然是一种有效的方法:)
【解决方案2】:

您可以从线性插值角度处理此问题。假设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,但需要以下假设:

此代码适用于以下假设:

  1. z 开头和结尾都没有负数
  2. 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

【讨论】:

  • 另外,人们可能想要指定外推参数,以解释结束元素为负数的情况(我建议'nearest' 外推算法在这里)
  • 可能是最好的方法!
  • @BenVoigt - 正确。让我换个帖子。
  • @BenVoigt - 我假设第一个和最后一个元素不是负数,尽管你有一个外推点。
  • interp1 的替代方法很好:) +1
【解决方案3】:

试试这个:

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

但这并不完全正确。在以下情况下会发生什么:

  • 就像@Ĭnfernal Seraphím 的问题一样,邻居也是负面的。
  • 如果第一项和最后一项是负数?

【讨论】:

  • 我打错了。我会解决的。
  • 还有一条评论。 abovebelow 实际上什么都不做。它基本上等于index。你的意思是aboveabove = max(index - 1, 1);belowbelow = min(index + 1, length(z)); 吗??
猜你喜欢
  • 2020-10-03
  • 1970-01-01
  • 2016-11-09
  • 2019-10-07
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多