2012-02-21 2 views
3

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

+0

ли вы * у * использовать строки? Похоже, количество возможных строк у вас довольно низкое; Не могли бы вы просто заменить каждую строку на число? Это, вероятно, ускорит многое! –

+0

Ну, я должен использовать строки. Я читаю текстовый файл с несколькими параграфами документа, от d1 до d13. Я должен использовать их для выполнения других вычислений. Итак, я не уверен, что замена каждой строки номером будет работать отлично для меня. Есть ли другой метод? – user1222437

+0

Вам не нужен цикл for, «cellfun» позаботится об этом. Вы просто используете один и тот же код несколько раз с тем же результатом. – yuk

ответ

2

Старт с

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

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

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

У меня сейчас нет MATLAB, но я думаю, что это должно заставить вас идти в правильном направлении. – macduff

+0

Я пробовал приведенный выше код, и 'count_string' отображает 1 для каждого вхождения строки в e, в d. Но как я могу подсчитать количество вхождений каждой строки? Как и в случае, если «тело» появляется дважды и «мышца» один раз в е, тогда count_string должен отображать (0,2,1,0). Спасибо за вашу помощь. – user1222437

+0

Я только отформатировал ответ, не изменил код. Первая строка должна быть 'count_string = zeros (size (d));'. В for-loop: 'count_string (i) = ...'. И 'd' и' e' следует переключать, как в вопросе. – yuk

3

Вы можете рассчитывать вхождения строки из d в e так:

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

Для ваших данных выборки вы получите вектор [0 2 1 0];

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

ОБНОВЛЕНИЕ:

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

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

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

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

+0

Это работает отлично! Большое спасибо. Да, массив d содержит только уникальные строки. Кроме того, мне нужно выполнить эту функцию на 13 других массивах ячеек строк, каждая приблизительно 1x140. Есть ли способ ускорить процесс? Я также должен вычислить сходство косинусов для 13 векторов, которые я выхожу из вышеупомянутой операции. Мой компилятор Matlab навсегда выполняет код. Не могли бы вы помочь? – user1222437

+0

Проверьте обновление ответа. – yuk

+0

Функция grp2idx спасла меня! Я не знал об этом раньше. Еще одно новое обучение в Matlab. Спасибо за вашу помощь. – user1222437

0

Что касается ошибок с вашим оригинальным решением для цикла, 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 
    
  • When добавив значения в count_string, вы должны использовать () -индекс для числовых массивов и {} -indexi ng для массивов ячеек.

  • Вы должны поменять 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 
Смежные вопросы