1

并感谢您对我的帖子表现出兴趣:)

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

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

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

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

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

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

现在,这是我的问题的简化;本质上,我正在使用更多数据,并且我正在重复此过程以找到更多数量的新向量/矩阵。关于简化,我已经设法通过这样做来解决问题:

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”中对应的值)。

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

非常感谢您提前。

约翰

4

1 回答 1

1

让我们一步一步解决这个问题:我假设FIT_txt是一个Nx1元胞数组并且sector是一个Mx1元胞数组。

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

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

这为您N提供了 FIT_txt 每一行的单元格,每个单元格中都有在每行中sector(ii)找到的实际位置。你只需要每行的计数,所以使用numel来获得:

cellfun(@numel,sector_occurrence );

sector您可以使用循环或使用arrayfun对每个元素执行此操作:

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

现在你有一个 NxM 矩阵。sector(j)第 i 行和第 j 列的元素告诉在 中出现了多少次FIT_txt(i)

*阅读您的评论...啊,但是如果找到一个扇区,则 FIT_txt 正好等于该扇区,这使您可以使用 strcmp 和 arrayfun 简化上述所有操作:

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



现在总结:

它只是出现向量与 的向量乘积,您可以通过将矩阵与FIT_num相乘来一次调用得到它们:sector_occurrenceFIT_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不会等于也不等于Bbb只有b

大数据集备注

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

sumresult=NaN(numel(sector),1); %preallocation is a good thing
for ii=1:numel(sector)
    sumresult(ii)=sector_occurrence(:,ii)'*FIT_num;
end
于 2012-08-01T13:46:50.113 回答