Ну, лучший ответ для этого потребует знания того, как заполняется А. Если 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 с ожидаемым значением для сколько раз индекс должен появиться в С.
% 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, объем памяти вашего компьютера и так далее. Тем не менее, мне все еще любопытно, какие решения могут сделать другие люди для этого х). Мне понравилось решение chappjc, хотя у него есть минусы, которые он указал.
Для данного примера (10k раз):
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.
является 'B' всегда непрерывен как' 1: n'? Это облегчило бы работу, так как вам не нужно будет проверять B в A, но проверьте каждую строку A и заполните ячейку C, когда появятся индексы. – Werner
@Ashwin: Ваше выражение для 'C' недопустимо, но я предполагаю, что вы имеете в виду' C = {[2,3,4]; [4]; [1,2,3]; [1,3,4] [1,2]} '. Это правильно? Если да, см. Мой ответ. Надеюсь, это поможет. – chappjc
@ Вернер, да, это правильно. Я обновил описание проблемы с помощью этой детали. –