我有一个包含n个维度的数组,并且我在所有其他维度上的某个位置沿着一个维度有一个序列。如何找到此序列的位置?最好没有循环。
我使用matlab。我知道它应该是什么尺寸,但顺序不一定存在。查找和==不工作。我可以使用crosscorrelation创建一个nd find函数,但我猜这已经实现了,我只是不知道要调用什么函数。
示例:
ND = rand(10,10,10,10);
V = ND(randi(10),randi(10),randi(10),:);
[I1, I2, I3] = find(ND==V);
编辑:要找到的序列跨越它所在的整个维度,我没有在我原来的问题表述中提到这一点。 Knedlsepp的解决方案完全解决了我的问题,但Luis的解决方案解决了一个更普遍的问题,因为序列不一定跨越整个维度。
答案 0 :(得分:4)
由于有多种方法可以解释您的问题,我将澄清:此方法假定大小为1D序列:numel(V) == size(ND, dimToSearch)
。因此,对于V = [1,2]
和ND = [1,2,1,2]
,它不适用。如果你想要这个功能,请使用 Luis Mendo 的答案,否则这可能会更快。
这将是使用bsxfun
:
我们从一些示例数据开始:
ND = rand(10,10,10,10);
V = ND(3,2,:,3);
如果您没有在正确维度(在本例中为V
)中给出向量[1,1,10,1]
,则可以按以下方式对其进行整形:
dimToSearch = 3;
Vdims = ones(1, ndims(ND));
Vdims(dimToSearch) = numel(V);
V = reshape(V, Vdims);
现在我们生成一个将保存匹配索引的单元格:
I = cell(1, ndims(ND));
此时我们会计算ND
的大小,如果它沿着维度dimToSearch
折叠(我们根据dimToSearch
计算V
,因为此时它会有正确的尺寸):
dimToSearch = find(size(V)>1);
collapsedDims = size(ND);
collapsedDims(dimToSearch) = 1;
最后我们实际寻找模式的部分:
[I{:}] = ind2sub(collapsedDims, find(all(bsxfun(@eq, ND, V), dimToSearch)));
这是通过以下方式完成的:bsxfun(@eq, ND, V)
将隐式repmat
数组V
,因此它与ND
具有相同的维度并进行相等比较。在此之后,我们会与all
进行核对,以查看维度dimToSearch
中的所有条目是否相同。然后,对find
和ind2sub
的调用将为您的数据生成正确的索引。
答案 1 :(得分:2)
让d
成为搜索的维度。我假设所寻求的序列V
可能比size(ND,d)
短。因此,序列可能会出现一次,不止一次,或永远不会出现在每个维度上 - d
- "线程"。
以下代码使用num2cell
将ND
重新整形为单元格数组,以便每个维度 - d
- 线程位于不同的单元格中。然后将strfind
应用于每个单元格以确定与V
的匹配,结果是与ND
具有相同尺寸的单元格数组,但维度d
是单身。每个单元格的内容告诉匹配的d
- 维度位置(如果有)。
感谢@knedlsepp建议使用num2cell
,这大大简化了代码。
ND = cat(3, [1 2 1 2; 3 4 5 6],[2 1 0 5; 0 0 1 2] ); %// example. 2x4x2
V = 1:2; %// sought pattern. It doesn't matter if it's a row, or a column, or...
d = 2; %// dimension along which to search for pattern V
result = cellfun(@(x) strfind(x(:).', V(:).'), num2cell(ND,d), 'UniformOutput', 0);
这给出了
ND(:,:,1) =
1 2 1 2
3 4 5 6
ND(:,:,2) =
2 1 0 5
0 0 1 2
V =
1 2
result{1,1,1} =
1 3 %// V appears twice (at cols 1 and 3) in 1st row, 1st slice
result{2,1,1} =
[] %// V doesn't appear in 2nd row, 1st slice
result{1,1,2} =
[] %// V appears appear in 1st row, 2nd slice
result{2,1,2} =
3 %// V appears once (at col 3) in 2nd row, 2nd slice
答案 2 :(得分:0)
这不是一种非常理想的方式:
dims = size(ND);
Vrep = repmat(V, [dims(1), dims(2), dims(3), 1]);
ND_V_dist = sqrt(sum(abs(ND.^2-Vrep.^2), 4));
iI = find(ND_V_dist==0);
[I1, I2, I3] = ind2sub([dims(1), dims(2), dims(3)], iI);