我是MATLAB的新手,我正在努力理解数组和元素操作之间的细微差别.我正在使用大型数据集,我发现最简单的方法并不总是最快的.我有一个非常大的字符串Cell数组,就像在这个简化的例子中一样:
% A vertical array of same-length strings
CellArrayOfStrings = {'aaa123'; 'bbb123'; 'ccc123'; 'ddd123'};
Run Code Online (Sandbox Code Playgroud)
我正在尝试提取一个子串数组,例如:
'a1'
'b1'
'c1'
'd1'
Run Code Online (Sandbox Code Playgroud)
我很满意这样的元素参考:
% Simple element-wise substring operation
MySubString = CellArrayOfStrings{2}(3:4); % Expected result is 'b1'
Run Code Online (Sandbox Code Playgroud)
但是,我无法一劳永逸地将这些符号全部引用,如下所示:
% Desired result is 'a1','b1','c1','d1'
MyArrayOfSubStrings = CellArrayOfStrings{:}(3:4); % Incorrect notation!
Run Code Online (Sandbox Code Playgroud)
我知道Matlab能够执行非常快速的数组操作,例如strcat,所以我希望有一种技术能够以类似的速度运行:
% An array-wise operation which works quickly
tic
speedTest = strcat(CellArrayOfStrings,'hello');
toc % About 2 seconds on my machine with >500K array elements
Run Code Online (Sandbox Code Playgroud)
所有使用幕后迭代的for循环和函数我尝试使用我的数据集运行得太慢了.是否有一些阵列方式表示法会这样做?有人能够纠正我对元素和阵列操作的理解吗?!非常感谢!
我无法一次性使用符号来引用它们,如下所示:
MyArrayOfSubStrings = CellArrayOfStrings{:}(3:4); % Incorrect notation!
这是因为大括号 ( {}) 返回一个逗号分隔的 list,相当于将这些单元格的内容按如下方式写入:
c{1}, c{2}, and so on....
当下标索引仅指一个元素时,MATLAB 的语法允许()在大括号后使用括号 ( ) 并进一步提取子数组(在您的情况下为子字符串)。但是,当逗号分隔列表包含多个项目时,禁止使用此语法。
那么有哪些替代方案呢?
使用for循环:
MyArrayOfSubStrings = char(zeros(numel(CellArrayOfStrings), 2));
for k = 1:size(MyArrayOfSubStrings, 1)
MyArrayOfSubStrings(k, :) = CellArrayOfStrings{k}(3:4);
end
Run Code Online (Sandbox Code Playgroud)使用cellfun(Dang Khoa答案的一个轻微变体):
MyArrayOfSubStrings = cellfun(@(x){x(3:4)}, CellArrayOfStrings);
MyArrayOfSubStrings = vertcat(MyArrayOfSubStrings{:});
Run Code Online (Sandbox Code Playgroud)如果您的原始元胞数组包含固定长度的字符串,则可以按照Dan的建议将元胞数组转换为字符串数组(字符矩阵),对其进行整形并提取所需的列:
MyArrayOfSubStrings =vertcat(CellArrayOfStrings{:});
MyArrayOfSubStrings = MyArrayOfSubStrings(:, 3:4);
Run Code Online (Sandbox Code Playgroud)使用更复杂的方法,例如正则表达式:
MyArrayOfSubStrings = regexprep(CellArrayOfStrings, '^..(..).*', '$1');
MyArrayOfSubStrings = vertcat(MyArrayOfSubStrings{:});
Run Code Online (Sandbox Code Playgroud)有很多解决方案可供选择,只需选择最适合您的解决方案即可 :) 我认为使用 MATLAB 的 JIT 加速,在大多数情况下,一个简单的循环就足够了。
另请注意,在我的所有建议中,获得的子字符串单元格的单元格数组被转换为字符串数组(矩阵)。这只是为了举例;显然,您可以将子字符串存储在元胞数组中,如果您决定这样做的话。