Что ж, лучший ответ на это потребует знания того, как заполняется A. Если A разреженный, то есть если он имеет несколько значений столбцов, а B довольно большой, то я думаю, что лучшим способом экономии памяти может быть использование разреженной матрицы вместо ячейки.
% No fancy stuff, just fast and furious
bMax = numel(B);
nRows = size(A,1);
cLogical = sparse(nRows,bMax);
for curRow = 1:nRows
curIdx = A(curRow,:);
cLogical(curRow,curIdx) = 1;
end
Отвечать:
cLogical =
(2,1) 1
(3,1) 1
(4,1) 1
(4,2) 1
(1,3) 1
(2,3) 1
(3,3) 1
(1,4) 1
(3,4) 1
(4,4) 1
(1,5) 1
(2,5) 1
Как прочитать ответ. Для каждого столбца строки показывают индексы, которые индекс столбца появляется в A. То есть 1
появляется в строках [2 3 4]
, 2
появляется в строке [4]
, 3
строк [1 2 3]
, 4
строке [1 3 4]
, 5
в строке [1 2]
.
Затем вы можете использовать cLogical
вместо ячейки в качестве матрицы индексации в будущем для своих нужд.
Другим способом было бы выделить C с ожидаемым значением того, сколько раз индекс должен появиться в C.
% Fancier solution using some assumed knowledge of A
bMax = numel(B);
nRows = size(A,1);
nColumns = size(A,2);
% Pre-allocating with the expected value, an attempt to reduce re-allocations.
% tic; for rep=1:10000; C = mat2cell(zeros(bMax,nColumns),ones(1,bMax),nColumns); end; toc
% Elapsed time is 1.364558 seconds.
% tic; for rep=1:10000; C = repmat({zeros(1,nColumns)},bMax,1); end; toc
% Elapsed time is 0.606266 seconds.
% So we keep the not fancy repmat solution
C = repmat({zeros(1,nColumns)},bMax,1);
for curRow = 1:nRows
curIdxMsk = A(curRow,:);
for curCol = 1:nColumns
curIdx = curIdxMsk(curCol);
fillIdx = ~C{curIdx};
if any(fillIdx)
fillIdx = find(fillIdx,1);
else
fillIdx = numel(fillIdx)+1;
end
C{curIdx}(fillIdx) = curRow;
end
end
% Squeeze empty indexes:
for curRow = 1:bMax
C{curRow}(~C{curRow}) = [];
end
Отвечать:
>> C{:}
ans =
2 3 4
ans =
4
ans =
1 2 3
ans =
1 3 4
ans =
1 2
Какое решение будет работать лучше всего? Вы выполняете тест производительности в своем коде, потому что он зависит от размера A, bMax, объема памяти вашего компьютера и так далее. Тем не менее, мне все еще любопытны решения, которые другие люди могут сделать для этого x). Мне понравилось решение chappjc, хотя у него есть минусы, на которые он указал.
Для данного примера (10 тыс. раз):
Solution 1: Elapsed time is 0.516647 seconds.
Solution 2: Elapsed time is 4.201409 seconds (seems that solution 2 is a bad idea hahaha, but since it was created to the specific issue of A having many rows it has to be tested in those conditions).
chappjc' solution: Elapsed time is 2.405341 seconds.
person
Werner
schedule
04.10.2013
B
непрерывен, как1:n
? Это облегчило бы работу, поскольку вам не нужно было бы проверять B в A, а нужно было бы проверять каждую строку A и заполнять ячейку C по мере появления индексов. - person Werner   schedule 04.10.2013C
неверно, но я предполагаю, что вы имеете в видуC = {[2,3,4];[4];[1,2,3];[1,3,4];[1,2]}
. Это правильно? Если да, то смотрите мой ответ. Надеюсь, это поможет. - person chappjc   schedule 04.10.2013