Performance 用NAN替换选择性数字

Performance 用NAN替换选择性数字,performance,matlab,matrix,nan,Performance,Matlab,Matrix,Nan,我有八列数据。列1、3、5和7包含3位数字。第2、4、6和8列包含1和0,分别对应于1、3、5和7。如果偶数列中有零,我想将相应的数字改为NaN。更简单地说,如果是 155 1 345 0 328 1 288 1 884 0 145 0 326 1 332

我有八列数据。列1、3、5和7包含3位数字。第2、4、6和8列包含1和0,分别对应于1、3、5和7。如果偶数列中有零,我想将相应的数字改为NaN。更简单地说,如果是

155            1           345           0
328            1           288           1
884            0           145           0
326            1           332           1
159            0           186           1
然后,884将被NaN替换,159、345和145也将被替换,其他数字保持不变。我需要使用NaN以矩阵形式维护数据。 我知道我可以用

data(3,1)=Nan; data(5,1)=Nan

等等,但这非常耗时。任何建议都是非常受欢迎的。

我会将问题分成两个矩阵,一个是逻辑掩码,另一个保存数据

data = your_mat(:,1:2:end);
valid = your_mat(:,2:2:end);
然后你可以简单地做:

data(~valid)=NaN;
然后,您可以通过执行以下操作重建数据:

your_mat(:,1:2:end) = data;

方法1

a1 = [
    155            1           345           0
    328            1           288           1
    884            0           145           0
    326            1           332           1
    159            0           186           1]

t1 = a1(:,[2:2:end])
data1 = a1(:,[1:2:end])

t1(t1==0)=NaN
t1(t1==1)=data1(t1==1)

a1(:,[1:2:end]) = t1
输出-

a1 =

   155     1   NaN     0
   328     1   288     1
   NaN     0   NaN     0
   326     1   332     1
   NaN     0   186     1
方法2

[x1,y1] = find(~a1(:,[2:2:end]))
a1(sub2ind(size(a1),x1,2*y1-1)) = NaN

这里有一个替代方案。您可以按以下方式使用
circshift

首先创建与输入矩阵a大小相同的偶数列的掩码:

AM = false(size(A)); AM(:,2:2:end) = true;
然后将掩码
(A==0)&AM
向左移动一个元素,以在奇数列上移动此掩码

A(circshift((A==0)&AM,[0 -1])) = nan;
注意:我已经搜索了一条直线。。。我认为这不是一个好的解决方案,但根据我的解决方案,这里有一个您可以使用的解决方案:

A(circshift(bsxfun(@and, A==0, mod(0:size(A,2)-1,2)),[0 -1])) = nan;

bsxfun
bsxfun
的麻烦在于在线创建掩码AM。我用在索引向量上的奇异性测试,
bsxfun
将它扩展到整个矩阵a。当然,你可以做任何其他事情来创建这个掩码。

这是一个有趣的解决方案,我希望它能很好地执行,但请注意它有点棘手

data(~data(:,2:end))=NaN

使用逻辑索引:

even = a1(:,2:2:end);    % even columns
odd  = a1(:,1:2:end);    % odd columns
odd(even == 0) = NaN;    % set odd columns to NaN if corresponding col is 0
a1(:,1:2:end)  = odd;    % assign back to a1

a1 = 
   155     1   NaN     0
   328     1   288     1
   NaN     0   NaN     0
   326     1   332     1
   NaN     0   186     1

+1表示方法2,但Raab70的答案似乎将主导方法1。谢谢,我同意我的答案有点简单,但方法2真的很有趣。同意@DennisJaheruddin!方法1是我所需要的。事实上,@Raab70的回答对我来说稍微简单一点。虽然没有提到的问题,我只需要t1数据,所以方法2不完全是我想要的。谢谢。这似乎有效,但我不确定我是否理解你最后的评论。“循环移位法总是需要一个完整的面具,对吗?”丹尼斯·贾鲁丁说真的,我不是很清楚。我只想强调生成掩码的方法(取索引向量的模)不是唯一的,您可以在这里做您想做的事情。但是,是的,你必须构建一个完整的掩码。这是可行的,但是,尽管不是最初的问题,我需要一个最终的矩阵,它只包含带NaN的列,而不是参考号。尝试使用一行程序,但收到错误消息“undefined function或variable“a”。但是我可能做错了什么。@user3560490我更正了一行,这必须是“a”而不是“a”。如果你只想要带数字的矩阵,这就简单多了,其他答案也可以,很抱歉误解了:)这很好。我想我知道circshift是如何工作的,但没有得到bsxfun,所以我会接受整个线路的现状。有趣的解决方案。。。但是如果在任何奇数列中有一个0,则会失败:您将在屏蔽列中写入nan。@Bentoy13,如前所述,这有点棘手。然而,当问题提到3位数字时,这应该是可以的。哦,你完全正确!我忘记了这个限制,所以我搜索得太远了。。。恭喜!精彩的一行!我在问题中没有提到,实际上只需要带有NAN的数据列,而不需要引用列。欢迎使用堆栈溢出!很高兴看到你想做出贡献,但要确保除了阅读问题外,还要检查现有的答案。在这种情况下,@Raab70的现有答案实际上是相同的,因此通常不鼓励发布。只要环顾四周,我相信你会发现足够的问题,你可以帮助提问者!我的缺点是,我在发布后注意到了这一点。事实上,我对编写代码非常陌生,所以用注释清楚地列出代码非常有帮助。谢谢