【问题标题】:replace zero values with previous non-zero values用以前的非零值替换零值
【发布时间】:2015-08-24 02:28:53
【问题描述】:

我需要一个在 Matlab 中快速的方法来做这样的事情(我正在处理巨大的向量,所以一个正常的循环需要很长时间!):

来自像

这样的向量
[0 0 2 3 0 0 0 5 0 0 7 0]

我需要得到这个:

[NaN NaN 2 3 3 3 3 5 5 5 7 7]

基本上,每个零值都替换为前一个非零值的值。第一个是NaN,因为之前没有非零元素 在向量中。

【问题讨论】:

  • 最接近或上一个,您的示例输出显示您正在用以前的非零值替换零,而不是最接近的...
  • 是的,对不起..你是对的..我想要前一个。我会修改问题..
  • 可能有趣的替代代码:stackoverflow.com/questions/27950664/…

标签: matlab indexing vectorization


【解决方案1】:

试试这个,但不确定速度。必须运行,所以如果您需要,稍后必须进行解释:

interp1(1:nnz(A), A(A ~= 0), cumsum(A ~= 0), 'NearestNeighbor')

【讨论】:

  • 是的,效果很好,而且速度够快!谢谢!
  • Matlab2012 列出了nearest -- 大概是和NearestNeighbor 一样的方法?
  • @CarlWitthoft docs (2015a)'nearest' 也是我的错误(尽管它似乎工作正常)
【解决方案2】:

试试这个(它使用 cummax 函数,在 R2014b 中引入):

i1 = x==0;
i2 = cummax((1:numel(x)).*~i1);
x(i1&i2) = x(i2(i3));
x(~i2) = NaN;

【讨论】:

  • 我有一个旧版本的 Matlab.. 我不能尝试它.. 但是谢谢!
  • @user1835630 如果你能找到 cummax 的源代码(或自己动手),你可以在任何 Matlab 版本中实现它。
  • @CarlWitthoft 不幸的是,它没有任何源代码,因为它是一个内置函数。这样做的好处是它非常快
  • 呃。这就是我喜欢开源的原因:-(
【解决方案3】:

仅供参考,以下是 Exchange Central 和/或 SO 列中的一些相似/相同的功能。

nearestpoint,

试试knnimpute函数。

或者最重要的是,一个专为完成您的任务而设计的功能:

repnan(显然,首先将您的零值替换为NaN

【讨论】:

    【解决方案4】:

    我曾经遇到过类似的问题,并决定处理它的最有效方法是编写一个mex 文件。 c++ 循环非常简单。在你弄清楚如何使用mex 接口之后,这将非常容易。

    【讨论】:

    • 我强烈反对处理语言缺陷的最佳方法是学习另外两种语言。 Matlab、Mathematica、R、Julia 等的重点是不必处理像cc++ 这样的低级语言。
    • @CarlWitthoft 感谢您的意见。当您对原始速度感兴趣时,Matlab 的能力是有限的。 Mex 是处理它的好方法(这就是它存在的原因)。看看 MathWorks - 你会看到大量的 mex 文件,正是因为这个原因。
    • 那里没有参数,但更好的回应(来自 Mathworks)是提供内置函数来编译/优化 Matlab 代码本身,例如,使用parfor 函数来简化多核操作。
    猜你喜欢
    • 2016-01-20
    • 2020-04-05
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多