我有一个包含各种数据类型的表。例如,
chars = {'a'; 'bc'; 'de'};
nums = [1; 20; 300];
tbl = table(chars, nums);
我想将所有数值列转换为字符数组变量。通过这个,我的意思是结果应该等同于如果我使用以下方法初始化表:
nums = {'1'; '20', '300'};
tbl = table(chars, nums);
我想尽可能快地做到这一点,因为我有一个可能有数百万行的表。
目前的工作解决方案:
首先,我得到数字列,在本例中,这将是第 2 列...
% Get the columns numbers which are numerical. This works fine, although a bit clunky.
numcols = find(varfun(@isnumeric, tbl(1,:), 'output', 'uniform'));
colnames = tbl.Properties.VariableNames(numcols); % Get the corresponding column names
然后,我有几种方法可以将这些数值列转换为字符数组类型,它们都涉及循环数值列并使用其他一些变相的循环___fun
函数......
arrayfun
for ii = 1:numel(colnames) % This arrayfun is *slow* for large tables tbl.(colnames{ii}) = arrayfun( @num2str, tbl.(colnames{ii}), 'uniformoutput', 0 ); end
num2cell
和cellfun
for ii = 1:numel(colnames) % num2cell is relatively quick tbl.(colnames{ii}) = num2cell( tbl.(colnames{ii}) ); % cellfun is about as slow as arrayfun, as might be expected tbl.(colnames{ii}) = cellfun( @num2str, tbl.(colnames{ii}), 'uniformoutput', 0 ); end
下面的速度测试,注意我只做一列和 1e5 个元素,而实际上我想做很多列和可能十倍的行,所以你可以清楚地看到速度问题......
% Setup
nums = (1:1e5).'; tbl = table(nums);
% Functions
f1 = @() arrayfun( @num2str, tbl.nums, 'uni', 0 );
f2 = @() cellfun( @num2str, num2cell(tbl.nums), 'uni', 0 );
% Timing
timeit(f1) % >> 5.15 sec
timeit(f2) % >> 5.16 sec
您可以看到这些方法基本上是等效的,这可能与它们的相似性所预期的一样。
有谁知道将表中的所有数据转换为字符数组变量类型的更快方法?我曾想过通过分类,但不知道如何在那里进行。
我更喜欢与 R2015b 兼容的解决方案。
注意:我的数据包含混合类型是相关的,因为我不能(也不想)varfun( ... )
在整个表上使用。