sumproduct条件是文本字符串匹配

时间:2012-08-01 12:53:50

标签: string matlab strcmp

感谢您对我的帖子感兴趣:)

让我快速描述一下我正在使用的数据:

我是从excel到我的matlab脚本的重要数据,所以我最终得到3个向量。这些是:

  • “FIT_txt”(〜250k行包含每个单元格中的混合字母和数字。重复输入)
  • “FIT_num”(与仅包含数字的“FIT_txt”相同的行数)
  • “sector”(每个单元格中包含混合字母和数字的~5k行。唯一条目)

现在,我想要实现的目标:

  1. 创建一个向量,计算“扇区”中每一行出现在“FIT_txt”中的次数。例如:说“扇区”中的第一个条目是“AB10”,那么我想创建一个向量来计算“AB10”出现在“FIT_txt”中的次数;这应该保存在新向量的第一行。新向量的第二行计算“FIT_txt”中“扇区”(例如“AB11”)的第2行的外观等。

  2. 创建一个向量,该向量将“FIT_num”中的所有数字添加到与“扇区”条目对应的“FIT_txt”中的条目相同的行中,并相应地对其进行排序。例如:“扇区”的第1行中的“AB10”在“FIT_txt”中出现3次 - 它出现在第2行,500行和“行”中。 2000.我想加入第2,500行和第2行。 2000年在“FIT_num”中将它们放入新载体的第一行。

  3. 现在,这是我的问题的简化;基本上,我使用了更多的数据,我正在重复这个过程,以找到更多的新矢量/矩阵。关于简化,我设法解决了这个问题:

    units = zeros(length(sector),1);
    installed = zeros(length(sector),1);    
    
    for a = 1:length(sector)
            for z = 1:length(FIT_txt(:,1))
    
                if strcmp((FIT_txt(z,1)),(sector(a)))==1
    
                    units(a,1) = units(a,1) + 1;
                    installed(a,1) = installed(a,1) + FIT_num(z,1);
    
                end
    
            end
        end
    

    不幸的是,我担心这种效率非常低,而且计算时间太长。

    我已经设法用我的第一个问题(计算外观)获得了不错的结果:

    units = zeros(length(sector),1);
    
    for a = 1:length(sector)
        units(a,1) = sum(strcmp((FIT_txt(:,1)),(sector(a)))
    end
    

    这样可以正常工作(尽管仍然比我想要的要长一些)但是,我不知道如何解决我的第二个问题(计算相应的“FIT_num”中的值)。

    如果您能帮助我找到解决问题的尽可能高效的解决方案,我将不胜感激。

    非常感谢你。

    约翰

1 个答案:

答案 0 :(得分:1)

让我们一步一步解决这个问题:我假设FIT_txt是一个Nx1单元格数组,sector是一个Mx1单元格数组。

首先找到FIT_txt中出现sector(ii)的行,以及多少次:

ii=1;
sector_occurrence = strfind(FIT_txt,sector(ii));

这为FIT_txt的每一行提供N个单元格,每个单元格中找到sector(ii)找到的每一行的实际位置。您只需要每行计数,因此请使用numel来获取:

cellfun(@numel,sector_occurrence );

您可以使用循环或arrayfunsector的每个元素执行此操作:

sector_occurrence = cell2mat(arrayfun(@(ii) cellfun(@numel,strfind(FIT_txt,sector{ii})),1:numel(sector),'uni',false'));

现在你有一个NxM矩阵。第i行和第j列的元素表示sector(j)FIT_txt(i)出现的次数。

*阅读你的评论...... Aah,但如果找到一个扇区,FIT_txt就完全等于扇区,这允许你用strcmp和arrayfun简化以上所有:

sector_occurrence = cell2mat(arrayfun(@(sectorii) strcmp(FIT_txt,sectorii), sector', 'uni',false))



现在进行总结:

它只是带有FIT_num的出现向量的向量积,你可以通过将sector_occurrence矩阵与FIT_num相乘来在一次调用中得到它们:

sumresult = sector_occurrence'*FIT_num;

请注意转置运算符',因为sector_occurrence定义为NxM

实施例

>> sector=[{'AB10'} ; {'b'}];
>> FIT_txt=[{'AB10'} ; {'a'} ; {'b'} ; {'ZX5b'} ; {'AB10'} ; {'b'}];
>> FIT_num = (1:6)';

>> sector_occurrence = strfind(FIT_txt,sector(ii))

sector_occurrence =

     1     0
     0     0
     0     1
     0     0
     1     0
     0     1

>> sumresult = sector_occurrence'*FIT_num

sumresult =

     6
     9

当然,它必须是一个完全匹配(你说它是)b不等于B而不是bb,只有{{1} }}

备注大数据集

b是一个sector_occurrence数组,所以它不需要那么多内存。但是当使用logical执行乘法时,它会转换为FIT_num,这需要8倍的空间。最终结果是一个小的(内存中)向量,但中间过程可以融化你的电脑。你可以通过在循环中进行乘法来避免这种情况:

float