Interplay of values between two vectors in Matlab
我有两个等长的向量o和c:
1 2
| o = [-1 -1 -1 0 0 0 1 1 0 0];
c = [-1 -1 -1 -1 0 1 1 1 0 -1]; |
o代表打开信号(负或pos),c代表关闭信号,假设打开信号之前带有相反的符号。一次只能激活一个信号,因此必须忽略连续性信号。在上面的两个向量中,我的第一个信号在o(1)中,而其对应的关闭信号在c(6)中。这也意味着应该忽略o(2)和o(3)中的打开信号,并且在o(7)处找到我的下一个打开信号,并在c(10)处将其相应的关闭,因此导致在o(8)
我正在尝试找到一种矢量化的解决方案,以识别打开/关闭信号的正确序列或索引,以产生以下解决方案示例的内容:
1 2
| o = [-1 0 0 0 0 0 1 0 0 0];
c = [ 0 0 0 0 0 1 0 0 0 -1]; |
我显然可以通过遍历for循环中的每个元素来解决此问题,但是由于我的数据集最多可以包含数百万个元素,而且我发现Matlab中的循环可能相当"昂贵",如果有人解决我的问题的方法是更面向矩阵的,还是通过arrayfun或等同的方法使代码更有效?
- 目前尚不清楚向量中的-1、0和1是什么意思。
-
@Patrik:如果c的最后一个元素是1,则会更有意义。您对如何创建o和c有任何控制权吗?
-
@shahar_m:值表示信号(-1/1-零表示无信号)。信号在o上打开,在c上关闭。
-
@eat:否,最后一个元素i c关闭在o(7)中打开的正信号,因此关闭信号必须为负。是的,我确实控制如何创建o和c。它们是在值高于或低于阈值时根据时间序列生成的。 c的阈值低于o
-
@Patrik:那么我可以假设模式是简单的交替正/负或负/正1吗?
-
@eat:o中的信号可以为正或负(1 / -1),并由c中具有计数器值(-1/1)的下一个元素关闭。对于何时在o或c中出现信号,没有特定的模式。我只能有一个活动的打开信号,因此需要删除"冗余"信号。不知道这是否能回答您的问题。
-
@Patrik:很可能存在一个简单的解决方案。只是无法从您的描述中找到答案。您可以通过循环和/或更多示例显示解决此问题的代码吗?谢谢
您可以使用diff以及一些逻辑运算来获取答案。
1 2 3 4 5 6
| o= [- 1,- 1,- 1, 0, 0, 0, 1, 1, 0, 0];
oFinal= abs(diff([0,o ])).*o;
oFinal=
- 1 0 0 0 0 0 1 0 0 0 |
诀窍是diff的输出和原始向量o都仅在o中第一次出现该值时才在同一索引处具有非零值(即,第一次出现在o中)链)。因此,通过将它与o逐个元素相乘,即可得到答案。 abs是为了确保不会由于diff的输出而发生符号变化。
c的方法与此类似,我将留给您尝试:)
-
谢谢。我看到您的解决方案确实适用于我给出的示例。不幸的是,我可以拥有稍微复杂一些的数据,例如o=[1,1,0,1,0]和c=[1,1,0,1,-1]。在这种情况下,o的diff将创建o=[1,0,0,1,0] (using your method with a leading zero) but I would actually want to ignore the signal in o(4)`,因为o(1)信号直到c(5)才关闭。不过,非常感谢您的建议。
-
抱歉,我之前不明白您的问题,但现在知道了。它比我简单地使用diff要复杂得多,但我可以肯定的是,可以通过在其上构建循环而无需循环。我现在没有时间,但是当我想到一些东西时会更新它。
通常,循环并不比执行其他操作更昂贵,因为其他操作只是将循环隐藏在另一个函数(例如arrayfun)的后面。从您的文本中听起来,您只是选择了错误的算法。您的问题听起来很线性,即O(n),但是您写的关于循环的意思是O(n ^ 2)。拥有数百万个元素的二次运行时不是很好。
您想要的算法是这样的:
它可能需要一些优化,因为您没有详细描述,例如c和o信号的顺序是什么(例如,如果打开和关闭相同的索引,则首先处理打开或关闭,我的示例代码假定打开),或者信号的顺序是否总是正常,或者是否必须进行一些错误处理-但我想您会想到单循环的想法。
- 谢谢。您的建议与我目前正在执行的操作类似,但是由于这段代码占用了我的大部分处理时间,因此我希望有人能够使用一个"魔术"公式来加快处理速度。 :-)
-
对于上面的代码,matlab在带有2.5 x 10 ^ 6项的o和c向量上需要不到一秒钟的时间。基本上,我认为没有办法加速它,尤其是我认为没有必要-还是您进行其他一些计算(或者您有几百万个条目)?