【问题标题】:Batch strfind: finding lots of strings within lots of other strings批量 strfind:在大量其他字符串中查找大量字符串
【发布时间】:2015-11-23 07:19:55
【问题描述】:

问题:我有两个大的字符串数组AB。我想知道识别A 中哪些元素包含B 中哪些元素的最快方法。尤其是不循环可以做到吗?

最小示例:(我的实际 AB 分别包含 7,000,000 和 22,000 个字符串)

A = {'one';
     'two';
     'three';
     'four'};
B = {'ee';
     'xx';
     'r'};

示例的期望输出是

C = [ 0 0 0 ;
      0 0 0 ;
      1 0 1 ;
      0 0 1 ];

其中C 的行和列分别对应AB 的元素。就我的目的而言,如果C 返回where 中的字符串B 位于A 中的第一个索引,我只需要一个真/假答案,例如:

C = [ 0 0 0 ;
      0 0 0 ;
      4 0 3 ;
      0 0 4 ];

我尝试过的: This 帖子类似,只是他们正在寻找字符串排除其他字符串,因此regexp 提供了一个不错的解决方案——我认为这不适用于这里。对我们来说,循环可以完成这项工作,但太慢了:

for i=1:length(A);
    for j=1:length(B);
        C(i,j) = max([0,strfind(A{i},B{j})]); disp(C(i,j));
    end
end

或者,基本上是一样的,但是cellfun

AA = repmat(A,[1 length(B)]);
BB = repmat(B,[length(A) 1]);
C  = reshape(cellfun(@(a,b) max([0,strfind(a,b)]),AA(:),BB(:)),[length(A),length(B)]);

更大的例子: 我在一些更大的数组上测试了cellfun 方法(仍然比我需要的小):

N=10000; M=200;
A=cellstr(char(randi([97,122],[N,10])));  %// N random length 10 lowercase strings
B=cellstr(char(randi([97,122],[M,4])));   %// M random length 4 lowercase strings

tic;
AA=repmat(A,[1 length(B)]);
BB=repmat(B,[length(A) 1]);
C=reshape(cellfun(@(a,b) max([0,strfind(a,b)]),AA(:),BB(:)),[length(A),length(B)]); 
toc

Elapsed time is 21.91 seconds.

有什么想法吗? regexp 可以帮忙吗? ismember 可以帮忙吗?我卡在循环中了吗?

【问题讨论】:

  • 所以你的输出矩阵应该是 7,000,000 x 22,000 矩阵?这听起来不像是可以在内存方面处理的矩阵。

标签: string matlab vectorization cell-array


【解决方案1】:

一般来说,我建议您的预期输出矩阵在内存方面会很大,无论如何您都需要重新考虑您的方法。

如果你有一个较小的数据集,你可以这样做:

A = {'one';
     'two';
     'three';
     'four'};
B = {'ee';
     'xx';
     'r'};

%// generate indices
n = numel(A);
m = numel(B);
[xi,yi] = ndgrid(1:n,1:m);

%// matching
Ax = A(xi);
By = B(yi);
temp = regexp(Ax,By,'start');

%// localize empty cell elements
%// cellfun+@isempty is quite fast
emptyElements = cellfun(@isempty, temp);

%// generate output
out = zeros(n,m);
out(~emptyElements) = [temp{:}];

out =

     0     0     0
     0     0     0
     4     0     3
     0     0     4

【讨论】:

  • 很好地处理空元素。
  • 漂亮,正是我想要的。你对内存问题也是正确的。 FWIW 我应该提到,在我的情况下,我希望 C 非常稀疏,并且我不一定需要这种格式的 C。只需获取索引[Ci,Cj]=find(~cellfun(@isempty,temp)) 就足够了......虽然我不确定这个问题在内存方面是否更可行
  • 很高兴能帮上忙!
  • @Geoff 而不是find(~cellfun(@isempty,temp)),以下内容就足够了:[temp{:}] find 对于大型数据集来说非常慢!
猜你喜欢
  • 2015-09-22
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-16
  • 2015-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多