首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在每列的矩阵中找到最后两个非NaN唯一的观测值

在每列的矩阵中找到最后两个非NaN唯一的观测值
EN

Stack Overflow用户
提问于 2018-03-16 15:13:13
回答 2查看 184关注 0票数 0

我有一个矩阵A,我想找到每列最后两个非NaN值。

例如,生成以下矩阵:

代码语言:javascript
复制
A = [NaN, 3, NaN; 5  5  5; NaN  1  9;  4  1   4;  NaN  6   NaN;  6   2   9]

我想得到以下结果:

代码语言:javascript
复制
B =

     4     6     4
     6     2     9

我怎样才能以最有效的方式做到这一点,而不需要for-循环?

我尝试了以下方法:[row,col,v] = find(A,3,'last'),但是它返回了一些我不理解的内容:

代码语言:javascript
复制
row =

     5
     6


col =

     3
     3


v =

   NaN
     9
EN

回答 2

Stack Overflow用户

发布于 2018-03-16 15:54:41

find的第三个参数实际上找到了非零的实际位置。它按列进行搜索,并返回最后三个非零值及其实际值的行和列位置。NaN在技术上是非零的,这就是为什么它会返回给您。

首先,用NaN查找矩阵中所有不是find的位置。

代码语言:javascript
复制
[I,J] = find(~isnan(A));

这将返回非NaN值的行和列位置。我们现在得到:

代码语言:javascript
复制
>> [I,J]

ans =

     2     1
     4     1
     6     1
     1     2
     2     2
     3     2
     4     2
     5     2
     6     2
     2     3
     3     3
     4     3
     6     3

我们可以看到一个很好的模式形成。左列显示不是NaN的所有行位置,右边列告诉您是哪一列。

接下来,我们可以做的是对第二列,找到从一列到另一列的转换点。这将给出最后一个元素的位置,这些元素不是每个列的NaN。然后,我们可以减去这些指数1,给出第二个不是NaN的最后一个元素的位置。我们可以使用diff函数来帮助我们做到这一点,并检查距离何时为非零。请注意,这将使输出的大小减少1,因为我们正在计算成对的距离,但只需在末尾放置1,因为这意味着最后一列的结束,这是我们想要找到列的最后两个元素的地方:

代码语言:javascript
复制
>> d = [diff(J) ~= 0; 1];
>> [J d]

ans =

     1     0
     1     0
     1     1
     2     0
     2     0
     2     0
     2     0
     2     0
     2     1
     3     0
     3     0
     3     0
     3     1

现在,让我们以diff的输出为例,并将所有内容都提高1:

代码语言:javascript
复制
d(1:end-1) = d(1:end-1) | d(2:end);

这将使我们能够标记每个列的第二个最后一个元素来捕获:

代码语言:javascript
复制
>> [I J d]

ans =

     2     1     0
     4     1     1
     6     1     1
     1     2     0
     2     2     0
     3     2     0
     4     2     0
     5     2     1
     6     2     1
     2     3     0
     3     3     0
     4     3     1
     6     3     1

最后但同样重要的是,我们现在对上述矩阵的前两列进行采样,其中第三列为非零,将它们转换为线性索引,并对我们的矩阵进行采样。为此,我们将使用reshapesub2ind的组合:

代码语言:javascript
复制
loc = d ~= 0;
out = reshape(A(sub2ind(size(A), I(loc), J(loc))), 2, size(A,2));

因此:

代码语言:javascript
复制
>> out

out =

     4     6     4
     6     2     9

因此,最后的准则是:

代码语言:javascript
复制
[I,J] = find(~isnan(A));
d = [diff(J) ~= 0; 1];
d(1:end-1) = d(1:end-1) | d(2:end);
loc = d ~= 0;
out = reshape(A(sub2ind(size(A), I(loc), J(loc))), 2, size(A,2));

警告

这假设每个列至少有两个元素不是NaN

票数 3
EN

Stack Overflow用户

发布于 2018-03-16 15:49:56

如下所示:

代码语言:javascript
复制
A = [NaN, 3, NaN; 5  5  5; NaN  1  9;  4  1   4;  NaN  6   NaN;  6   2   9]
N=2; %last 2
IsOK=~isnan(A);
[~,I]=sort(IsOK);
Iok=I(end-N+1:end,:); %get last N
LinearIndxs=sub2ind(size(A), Iok, repmat(1:size(A,2),N,1));
Result=A(LinearIndxs)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49324057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档