我将假设您的输入数组是一个字符元胞数组,如下所示:
inputArray = {'Apple', 'Banana', 'Cherry', 'Dragonfruit', 'Apple', 'Cherry'};
您可以使用unique 函数的第三个输出将上述内容转换为数值数组。这样做的好处在于 unique 分配了一个唯一的 ID,按排序顺序,因此,如果您有一个字符元胞数组,它会遵守字符的字典顺序。
接下来,声明一个零矩阵(就像您在上面所做的那样),然后使用sub2ind 对矩阵进行索引并将值设置为 1。
类似的东西。请记住,我对输出的初始化略有不同。这是我学会分配一个非常快的零矩阵的技巧。见这里:Faster way to initialize arrays via empty matrix multiplication? (Matlab)
inputArray = {'Apple', 'Banana', 'Cherry', 'Dragonfruit', 'Apple', 'Cherry'};
[~,~,inputNum] = unique(inputArray);
inputNum = inputNum.'; %// To make compatible in dimensions
binMatrix(numel(inputArray), max(inputNum)) = 0;
binMatrix(sub2ind(size(binMatrix), 1:numel(inputArray), inputNum)) = 1;
另一种方法是创建一个sparse 逻辑数组,我们将正确的行和列位置设置为 1,然后使用它来索引我们的 zeroes 数组并相应地设置值。
类似:
inputArray = {'Apple', 'Banana', 'Cherry', 'Dragonfruit', 'Apple', 'Cherry'};
[~,~,inputNum] = unique(inputArray);
inputNum = inputNum.'; %// To make compatible in dimensions
binMatrix = sparse(1:numel(inputArray), inputNum, 1, numel(inputArray), max(inputNum));
binMatrix = full(binMatrix);
让我们将所有这些放在一个计时脚本中。我已经合并了上面的两种方法,加上你的旧方法,加上 Divakar 的(只有第一种方法)和 brodroll 的(非常巧妙的顺便说一句)方法。对于 Divakar 和 brodroll 的方法,我还使用了 unique 和第三个输出,因为您的原始查询有大写字母,这一切都令人困惑。使用第三个输出可以轻松地将他们以前的方法转换为您的新规范。
顺便说一句,您的示例和您的代码不匹配。您的示例设置了它,因此每一列都是一个索引,但它是每一行。对于时序测试,我将转置您的结果。我在 Mac OS X 10.10.3 上运行 MATLAB R2013a,配备 16 GB RAM 和 Intel i7 2.3 GHz 处理器。所以:
clear all;
close all;
%// Generate dictionary
chars = {'Apple', 'Banana', 'Cherry', 'Dragonfruit'};
rng(123);
%// Generate 50000 random words
v = randi(numel(chars), 50000, 1);
inputArray = chars(v);
[~,~,inputNum] = unique(inputArray);
inputNum = inputNum.'; %// To make compatible in dimensions
%// Timing #1 - sub2ind
tic;
binMatrix(numel(inputArray), max(inputNum)) = 0;
binMatrix(sub2ind(size(binMatrix), 1:numel(inputArray), inputNum)) = 1;
t = toc;
clear binMatrix;
%// Timing #2 - sparse
tic;
binMatrix = sparse(1:numel(inputArray), inputNum, 1, numel(inputArray), max(inputNum));
binMatrix = full(binMatrix);
t2 = toc;
clear binMatrix;
%// Timing #3 - ismember and for
tic;
binMatrix = zeros(numel(inputArray), numel(chars));
for i = 1: size(binMatrix,1)
binMatrix(i,:) = ismember(chars, inputArray(i));
end
t3 = toc;
%// Timing #4 - bsxfun
clear binMatrix;
tic;
binMatrix = bsxfun(@eq,inputNum',unique(inputNum)); %// Changed to make dimensions match
t4 = toc;
clear binMatrix;
%// Timing #5 - raw sub2ind
tic;
binMatrix(numel(inputArray), max(inputNum)) = 0;
binMatrix( (inputNum-1)*size(binMatrix,1) + [1:numel(inputArray)] ) = 1;
t5 = toc;
fprintf('Timing using sub2ind: %f seconds\n', t);
fprintf('Timing using sparse: %f seconds\n', t2);
fprintf('Timing using ismember and loop: %f seconds\n', t3);
fprintf('Timing using bsxfun: %f seconds\n', t4);
fprintf('Timing using raw sub2ind: %f seconds\n', t5);
我们得到:
Timing using sub2ind: 0.004223 seconds
Timing using sparse: 0.004252 seconds
Timing using ismember and loop: 2.771389 seconds
Timing using bsxfun: 0.020739 seconds
Timing using raw sub2ind: 0.000773 seconds
在排名方面:
- 原始
sub2ind
sub2ind
sparse
bsxfun
- OP的方法