Подсчет вхождений строки в массиве ячеек строк в Matlab - PullRequest
3 голосов
/ 21 февраля 2012

У меня есть два набора ячеек с цепочками различной длины: d = {'' нерв ',' тело ',' мышца ',' кость '} и e = {' тело ',' тело ',' мышца '}. Я должен сравнить эти два массива и посчитать вхождения каждой строки в e в d. Ожидаемый результат должен быть вектором count_string = (0,2,1,0). Ниже приведен код, который я написал, но я получаю сообщение об ошибке: Присвоение содержимого ячейки объекту массива, не являющемуся ячейкой. Я новичок в программировании Matlab. Любая быстрая помощь в этом очень ценится.

count_string=size(d)
for i=1:length(d)    
count_string{i}=sum(ismember(e{i},d));
end

После всех ваших предложений ниже, это модуль, который у меня есть.

for i=1:length(d_union)
count_string1=cellfun(@(x) sum(ismember(d1,x)), d_union);
count_string2=cellfun(@(x) sum(ismember(d2,x)), d_union);
count_string3=cellfun(@(x) sum(ismember(d3,x)), d_union);
count_string4=cellfun(@(x) sum(ismember(d4,x)), d_union);
count_string5=cellfun(@(x) sum(ismember(d5,x)), d_union);
count_string6=cellfun(@(x) sum(ismember(d6,x)), d_union);
count_string7=cellfun(@(x) sum(ismember(d7,x)), d_union);
count_string8=cellfun(@(x) sum(ismember(d8,x)), d_union);
count_string9=cellfun(@(x) sum(ismember(d9,x)), d_union);
count_string10=cellfun(@(x) sum(ismember(d10,x)), d_union);
count_string11=cellfun(@(x) sum(ismember(d11,x)), d_union);
count_string12=cellfun(@(x) sum(ismember(d12,x)), d_union);
count_string13=cellfun(@(x) sum(ismember(d13,x)), d_union);
count_string14=cellfun(@(x) sum(ismember(testdoc,x)), d_union);    end   

Мой компилятор Matlab работает вечно, чтобы выполнить этот модуль. 'd_union' является массивом ячеек 1x1216, и каждый из d1 для testdoc составляет массив ячеек приблизительно 1x240. Я должен вычислить косинусное сходство векторов, которые я получаю от вышеупомянутой операции. Есть ли способ ускорить процесс? Пожалуйста помоги. Спасибо.

Ответы [ 3 ]

3 голосов
/ 21 февраля 2012

Вы можете посчитать вхождения строк из d в e следующим образом:

count_string = cellfun(@(x) sum(ismember(e,x)), d);

В качестве примера данных вы получите вектор [0 2 1 0];

Содержит ли массив d только уникальные строки?

UPDATE :

Вот еще один метод временного преобразования строк в числа с GRP2IDX исчитая их с HISTC .Предполагается, что все строки в e также существуют в d.

[gi g] = grp2idx([d e]);
gn = histc(gi(numel(d)+1:end),1:numel(g));

g будут содержать уникальные строки (вероятно, будут идентичны d), а gn будетна счет.gi - это временный числовой массив, используемый для подсчета.

Для доступа к функции GRP2IDX вам необходим Statistical Toolbox.

2 голосов
/ 21 февраля 2012

Начните с

count_string = cell(1,size(d));  

И вы индексируете в e, но контролируете цикл размером d.

for i=1:length(d)
   count_string{i}=sum(ismember(d{i},e));
end
0 голосов
/ 24 февраля 2012

Что касается ошибок в исходном решении for-loop, macduff уже упомянул их:

  • Вам нужно инициализировать count_string, используя CELL или ZEROS :

    count_string = cell(size(d));   %# A 1-by-4 cell array
    %# OR
    count_string = zeros(size(d));  %# A 1-by-4 numeric array
    
  • При добавлении значений к count_string следует использовать () -индексирование для числовых массивов и {} -индексирование для массивов ячеек.

  • Вам необходимо поменять d и e при вызове на ISMEMBER и индексировать d с переменной цикла вместо e.

Что касается альтернативы использованию цикла, yuk дал вам одно решение с использованием CELLFUN . Другое векторизованное решение - использовать комбинацию ISMEMBER и ACCUMARRAY :

>> [~, index] = ismember(e,d);  %# Find where each entry in e occurs in d
>> count_string = accumarray(index.', 1, [numel(d) 1]).'  %# Accumulate indices

count_string =

     0     2     1     0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...