【问题标题】:Counting the occurrences of a string in a cell array of strings in Matlab在Matlab中计算字符串单元格数组中字符串的出现次数
【发布时间】:2012-02-21 03:26:12
【问题描述】:

我有两个不同长度的字符串元胞数组,d={'nerve','body','muscle','bone'} 和 e={'body','body','muscle'}。我必须比较这两个数组并计算 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 单元阵列。我必须计算从上述操作中得到的向量的余弦相似度。有没有办法加快这个过程?请帮忙。谢谢你。

【问题讨论】:

  • 使用字符串吗?看起来您可能拥有的字符串数量很少;你不能用一个数字替换每个字符串吗?这可能会加快速度!
  • 好吧,我必须使用字符串。我正在阅读一个包含多个文档段落 d1 到 d13 的文本文件。我必须使用这些来执行其他计算。所以,我不确定用数字替换每个字符串是否适合我。还有其他方法吗?
  • 你不需要 for 循环,cellfun 会处理这个问题。您只是多次运行相同的代码并获得相同的结果。

标签: string matlab count


【解决方案1】:

您可以像这样计算来自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 是用于计数的临时数值数组。

您需要 Statistical Toolbox 才能访问 GRP2IDX 功能。

【讨论】:

  • 这很好用!非常感谢。是的,d 数组只包含唯一的字符串。此外,我需要在其他 13 个字符串元胞数组上执行此函数,每个元胞数组大约为 1x140。有没有办法加快这个过程?我还必须计算从上述操作中得到的 13 个向量的余弦相似度。我的 matlab 编译器需要永远执行代码。你能帮忙吗?
  • grp2idx 函数救了我!我以前不知道这个。 matlab 中的另一个新知识。感谢您的帮助。
  • 如果答案有帮助,请考虑支持和/或接受它。
【解决方案2】:

开始

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

您正在索引e,但控制d 大小的循环。

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

【讨论】:

  • 我现在没有 matlab,但我认为这应该会让你朝着正确的方向前进。
  • 我尝试了上面的代码,'count_string' 为 e 中字符串的每次出现显示 1,在 d 中。但是我如何计算每个字符串的出现次数?如在 e 中,如果“body”出现两次,“muscle”出现一次,则 count_string 应显示 (0,2,1,0)。感谢您的帮助。
  • 我只是格式化了答案,没有更改代码。第一行应该是count_string = zeros(size(d));。在 for 循环中:count_string(i) = ...。并且de 应该像问题一样切换。
【解决方案3】:

关于你原来的 for 循环解决方案的错误,macduff 已经提到它们:

  • 您需要使用CELLZEROS 初始化count_string

    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 添加值时,您应该对数值数组使用()-indexing,对元胞数组使用{}-indexing。

  • 您需要在对ISMEMBER 的调用中交换de,并将d 索引为循环变量而不是e

关于使用循环的替代方案,yuk 为您提供了一种使用 CELLFUN 的解决方案。另一种矢量化解决方案是使用ISMEMBERACCUMARRAY 的组合:

>> [~, 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-06
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 2020-02-21
    • 2012-02-12
    相关资源
    最近更新 更多