Matlab:通过矢量化搜索具有固定第一个和最后一个元素的矩阵中的行

发布于 2024-12-27 16:23:31 字数 1181 浏览 5 评论 0原文

我有一个如下所示的矩阵(任意列/行):

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

现在我想获取第一个元素为特定值 X 且最后一个元素(即最后一个元素!= 0)为特定值 Y 的所有行,或转身:第一个是 Y,最后一个是 X。

看不到任何不使用 for 循环的快速代码:( 谢谢!

编辑:要过滤具有特定第一个元素的所有行非常简单,您不需要在这里帮助我。因此,假设我只想执行以下操作:过滤最后一个元素(即每行中最后一个元素!= 0)为 X 或 Y 的所有行。

编辑 非常感谢您的帖子。我使用 473408*10 元素的矩阵对三种可能的解决方案进行了基准测试。这是基准脚本: http://pastebin.com/9hEAWw9a

结果是:

t1 = 2.9425 Jonas
t2 = 0.0999 Brendan
t3 = 0.0951 Oli

非常感谢你们,我坚持使用奥利的解决方案从而接受它。感谢所有其他解决方案!

I have a matrix like the following (arbitrary cols/rows):

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

and now I want to get all rows where the first element is a certain value X and the last element (that is the last element != 0) is a certain value Y, OR turned around: the first is Y and the last is X.

Can't see any speedful code which does NOT use a for-loop :(
Thanks!

EDIT: To filter all rows with a certain first element is really easy, you don't need to help me here. So let's assume I only want to do the following: Filter all rows where the last element (i.e. the last element != 0 in each row) is either X or Y.

EDIT
Thanks a lot for your posts. I benchmarked the three possible solutions with a matrix of 473408*10 elements. Here's the benchmarkscript:
http://pastebin.com/9hEAWw9a

The results were:

t1 = 2.9425 Jonas
t2 = 0.0999 Brendan
t3 = 0.0951 Oli

So thanks a lot you guys, I'm sticking with Oli's solution and thus accept it. Thanks though for all the other solutions!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花期渐远 2025-01-03 16:23:31

您需要做的就是找到每行最后一个非零元素的线性索引。剩下的很简单:

[nRows,nCols] = size(A);
[u,v] = find(A); %# find all non-zero elements in A
%# for each row, find the highest column index with accumarray
%# and convert to linear index with sub2ind
lastIdx = sub2ind([nRows,nCols],(1:nRows)',accumarray(u,v,[nRows,1],@max,NaN));

要过滤行,您可以编写

goodRows = A(:,1) == X & A(lastIdx) == Y

All you need to do is to find the linear indices of the last non-zero element of every row. The rest is easy:

[nRows,nCols] = size(A);
[u,v] = find(A); %# find all non-zero elements in A
%# for each row, find the highest column index with accumarray
%# and convert to linear index with sub2ind
lastIdx = sub2ind([nRows,nCols],(1:nRows)',accumarray(u,v,[nRows,1],@max,NaN));

To filter rows, you can then write

goodRows = A(:,1) == X & A(lastIdx) == Y
谈情不如逗狗 2025-01-03 16:23:31

这里有一个技巧:查找右侧带有 0 的数字,然后将它们全部相加:

H=[1 2 0 0 0;
   2 3 1 0 0;
   4 5 8 0 0;
   8 5 4 2 2];

lastNumber=sum(H.*[H(:,2:end)==0 true(size(H,1),1)],2)

ans =

     2
     1
     8
     2

其余的很简单:

firstNumber=H(:,1);

find( (firstNumber==f) & (lastNumber==l) )

Here is a trick: Look for numbers with a 0 on the right, and sum them all:

H=[1 2 0 0 0;
   2 3 1 0 0;
   4 5 8 0 0;
   8 5 4 2 2];

lastNumber=sum(H.*[H(:,2:end)==0 true(size(H,1),1)],2)

ans =

     2
     1
     8
     2

The rest is easy:

firstNumber=H(:,1);

find( (firstNumber==f) & (lastNumber==l) )
我的黑色迷你裙 2025-01-03 16:23:31

仅当每行中的数字是 x 个非零后跟一系列零时,此方法才有效。也就是说,如果以下情况可能1 0 3 4 0 0,它将不起作用,我认为根据您提供的示例输入这是不可能的......

% 'a' is your array
[nx, ny] = size(a);
inds = [0:ny:ny*(nx-1)]' + sum(a ~= 0, 2);
% Needs to transpose so that the indexing reads left-to-right
aT = a'; 
valid1 = aT(inds) == Y;
valid2 = a(:,1) == X;
valid = valid1 & valid2;
valid_rows = a(valid,:);

我知道这很混乱......

This works only if the numbers in each row are x number of non-zeros followed by a series of zeros. i.e. it will not work if the following is possible 1 0 3 4 0 0, I assume that isn't possible based on the sample input you gave ...

% 'a' is your array
[nx, ny] = size(a);
inds = [0:ny:ny*(nx-1)]' + sum(a ~= 0, 2);
% Needs to transpose so that the indexing reads left-to-right
aT = a'; 
valid1 = aT(inds) == Y;
valid2 = a(:,1) == X;
valid = valid1 & valid2;
valid_rows = a(valid,:);

This is messy I know ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文