我有两个矩阵, A
和 B
. ( B
像 1:n
一样连续)
我需要在 A
中找到 B
的每一行的所有出现,并相应地将这些行索引存储在单元格数组 C
中 . 请参阅下面的示例 .
A = [3,4,5;1,3,5;1,4,3;4,2,1]
B = [1;2;3;4;5]
从而,
C = {[2,3,4];[4];[1,2,3];[1,3,4];[1,2]}
注意 C
不需要在我的应用程序的单元格数组中 . 我只建议它因为 C
的行向量长度不等 . 如果你可以建议一个解决方案,这也很好 .
我已经尝试使用循环运行ismember为 B
的每一行,但是当矩阵 A
和 B
很大时,这个太慢了,大约有一百万个条目 . 矢量化的代码表示赞赏 .
(为了给你上下文,这个目的是在网格中识别附加到单个顶点的那些面 . 注意我不能使用函数edgeattachments,因为我的数据在三角剖分表示中不是“TR”形式 . 我只有一个面部列表和顶点列表 . )
2 回答
那么,对此最好的答案需要知道A是如何填充的 . 如果A是稀疏的,也就是说,如果它具有很少的列值并且B非常大,那么我认为节省内存的最佳方法可能是使用稀疏矩阵而不是单元格 .
回答:
如何阅读答案 . 对于每列,行显示列索引在A中显示的索引 . 即
1
出现在行[2 3 4]
中,2
出现在行[4]
,3
行[1 2 3]
,4
行[1 3 4]
,5
行[1 2]
中 .然后,您可以根据需要使用
cLogical
而不是单元格作为索引矩阵 .另一种方法是为C分配一个索引在C中出现的次数的预期值 .
回答:
哪种解决方案效果最佳?您在代码中进行性能测试,因为它取决于A,bMax,计算机的内存大小等等 . 然而,我仍然对其他人可以为此x)做的解决方案感到好奇 . 我喜欢chappjc的解决方案,尽管它有他指出的缺点 .
对于给定的例子(10k次):
我们可以在不对
B
做任何假设的情况下做到这一点 . 尝试使用bsxfun
和mat2cell
:上面的
C
中的单元格将是列向量而不是示例中的行 . 要使单元格包含行向量,请改用C = mat2cell(ii',1,R)'
.我唯一担心的是
mat2cell
对于数百万的R
值来说可能会很慢,但如果你想在单元格中输出你的输出,我不确定你能做多少好 . EDIT :如果您可以像Werner的第一个解决方案那样处理稀疏矩阵,请使用以下内容替换上面的最后一行:不幸的是,如果
size(A,1)
和numel(B)
都很大,bsxfun
可能会耗尽内存!如果内存成为问题,您可能必须循环A
或B
的元素 . 这是通过在B
中循环遍历顶点来实现此目的的一种方法:是的,那很容易 . 在MATLAB中,单元阵列的增长非常快,因为它类似于存储对数据的连续引用的序列容器,而不是保持数据本身是连续的 . 也许
ismember
是你测试的瓶颈 .