Arrays matlab中的单元比较
让strCellArr是一个4000*1的单元数组。每个单元格都是一个字符串 判断每个单元格是否有长度为100的字符串的最快方法是什么 换句话说,我想要的东西和我的一样Arrays matlab中的单元比较,arrays,matlab,Arrays,Matlab,让strCellArr是一个4000*1的单元数组。每个单元格都是一个字符串 判断每个单元格是否有长度为100的字符串的最快方法是什么 换句话说,我想要的东西和我的一样 a= true; For (i =0; i =length(strCellArr); i++) if length(strCellArr{i}) ~= 100 a = false; end end 一个相关问题: 我可以使用 charArr = char(strCellArr); 但是,这将
a= true;
For (i =0; i =length(strCellArr); i++)
if length(strCellArr{i}) ~= 100
a = false;
end
end
一个相关问题:
我可以使用
charArr = char(strCellArr);
但是,这将在没有100个字符的行中引入空格。如果第34行只有30个字符。然后
charArr(34)(50)
将返回一个空格
在我的例子中(A、T、C或G),如何检查每个字符是否都是特定的字符。有没有不使用for循环的方法呢?对于第一个问题,您可以使用
all(cellfun(@length,strCellArr)==100)
,如果单元格中的每个元素都有100个元素的长度,则返回1表示“true”
对于第二个问题,您可以使用
all(ismember(charArr,A))
其中A=['A','T','C','G']
。有关更多信息,请参阅和的文档。关于您的第一个问题:这听起来像是一份工作cellfun
允许您对单元阵列中的每个单元进行操作。(另一方面,arrayfun
允许您在常规数组上执行相同的操作)。(请注意,您的原始代码不是MATLAB语法,尤其是for
循环。)
所以你可以做一些像
res = cellfun(@(x) length(x) == 100, strCellArr);
这里,res
将是一个逻辑
,因为=
条件将计算为0或1。然后,您可以看到结果中的所有
是否都是1,即strCellArr
中的所有字符串的长度都是100:
a = all(res);
if a == 0
disp('One or more strings does not have 100 characters!');
else
disp('All strings have 100 characters!');
end
哦,我只是喜欢像“什么是最快的方式做…”这样的问题 以下是一些备选方案和比较:
% Initalize
map = 'CATG';
strCellArr = cellfun(@(x) map(randi(4,100,1)),cell(4000,1), 'UniformOutput', false);
% Your original method
tic
a = true;
for el = strCellArr
if length(el{1}) ~= 100
a = false;
break;
end
end
toc
% My solution
tic
a = all(cellfun('length', strCellArr) == 100);
toc
% Dang Khoa's method
tic
a = all( cellfun(@(x) length(x) == 100, strCellArr) );
toc
% Engineero's method
tic
a = all(cellfun(@length, strCellArr) == 100);
toc
结果:
Elapsed time is 0.001158 seconds. % loop
Elapsed time is 0.000455 seconds. % cellfun; string argument
Elapsed time is 0.031897 seconds. % cellfun; anonymous function
Elapsed time is 0.006994 seconds. % cellfun; function handle
Elapsed time is 0.061168 seconds. % ismember
Elapsed time is 0.005098 seconds. % direct comparison to whitespace
鲜为人知的事实是:cellfun
的字符串输入是指直接内置在cellfun
二进制文件中的函数,因此不需要对匿名函数求值。换句话说,cellfun
不必在每次迭代中都通过MATLAB解释器,这使得它的速度非常快:)
现在,你问题的第二部分:
% Engineero
tic
A = 'ATCG';
all(all(ismember(char(strCellArr), A)));
toc
% My solution
tic
C = char(strCellArr);
~any(C(:)==' ');
toc
结果:
Elapsed time is 0.001158 seconds. % loop
Elapsed time is 0.000455 seconds. % cellfun; string argument
Elapsed time is 0.031897 seconds. % cellfun; anonymous function
Elapsed time is 0.006994 seconds. % cellfun; function handle
Elapsed time is 0.061168 seconds. % ismember
Elapsed time is 0.005098 seconds. % direct comparison to whitespace
这种差异的产生是因为ismember
是在MATLAB m-code中实现的,并且充满了旨在实现用户友好性的代码(错误检查、错误、警告等)、复杂的泛化、循环结构和许多其他东西,这些都是性能损失
由于我们事先知道,在将数组强制转换为char
时,只会将空格添加到数组中,因此我们不必显式地检查'A'
、'C'
、'T'
、'G'
的出现情况,而只检查它们是否消失。意思是,只需寻找那些空间:)
不用说,这些时间几乎都可以忽略不计,这更多的是精神上的自慰,而不是真正有用的。但这很有趣!:) 有趣的是,在我的解决方案中,将
==100
放在cellfun
内部,与放在外部相比,运行时间增加了455%!我想知道这是为什么。显然,在这种情况下,这是可以忽略的,但扩大问题的规模将是低效的。我认为从程序员的角度来看,我的解决方案更好,即“设计意图”比@Engineero的解决方案更清晰。但很明显,他以速度取胜。另外,谢谢你给我的关于:字符串参数的学习!我仍然更喜欢使用非FCN,同样是因为设计意图是明确的。但如果需要速度,这是好的。@DangKhoa:我同意。事实上,在MATLAB中,这种情况非常常见;糖衣越多,性能损失就越大。我认为区别在于@(x)
强制在MATLAB解释器中进行求值,而直接@length
只允许查找length
函数;它是一个函数句柄(可能是内置的)length
函数。所以“更短的匿名函数”有点用词不当。也就是说,Anon的速度稍慢一些(至少在过去是这样)。但是较长的匿名函数也只是做了更多(昂贵的)工作,包括额外的函数调用(=
和anon调用本身,在length()
之上)以及构建100
和临时变量。