通常你給出代表你的標籤(也稱爲類)的整數值的向量,例如我如何在Matlab中熱編碼?
[2; 1; 3; 3; 2]
和要熱一個編碼此載體中,使得每個值表示由在一個1柱由標籤向量的每一行中的值指示的,例如
[0 1 0;
1 0 0;
0 0 1;
0 0 1;
0 1 0]
通常你給出代表你的標籤(也稱爲類)的整數值的向量,例如我如何在Matlab中熱編碼?
[2; 1; 3; 3; 2]
和要熱一個編碼此載體中,使得每個值表示由在一個1柱由標籤向量的每一行中的值指示的,例如
[0 1 0;
1 0 0;
0 0 1;
0 0 1;
0 1 0]
可以使用單位矩陣和索引到它使用輸入/標籤向量,例如,如果標籤矢量X是一些隨機整數矢量
X = randi(3,5,1)
ans =
2
1
2
3
3
然後,下面將熱一個編碼X
eye(max(X))(X,:)
其可以方便地定義爲使用
hotone = @(v) eye(max(v))(v,:)
編輯功能:
儘管上述作品的溶液在八度,你有你修改它的Matlab如下
I = eye(max(X));
I(X,:)
剛剛發佈的sub2ind
解決方案太滿足您的好奇心:)
但我喜歡你的更好的解決方案:對
>> X = [2,1,2,3,3]'
>> LinearIndices = sub2ind([length(X),3], [1:length(X)]', X);
>> tmp = zeros(length(X), 3);
>> tmp(LinearIndices) = 1
tmp =
0 1 0
1 0 0
0 1 0
0 0 1
0 0 1
對於速度和節省內存,你可以使用bsxfun
與eq
相結合來完成一樣。儘管您的eye
解決方案可能有效,但您的內存使用量將以X
中的唯一值數量的平方增長。
Y = bsxfun(@eq, X(:), 1:max(X));
或者,如果你喜歡一個匿名函數:
hotone = @(X)bsxfun(@eq, X(:), 1:max(X));
或者,如果你在八度(或MATLAB版本R2016b及更高版本),你可以利用自動播放的,只是做正如@Tasos所建議的那樣。
Y = X == 1:max(X);
基準
在這裏是表示與上X
變化元件的數目和在X
不同的唯一值的數目的各種回答的效果的快速基準。
function benchit()
nUnique = round(linspace(10, 1000, 10));
nElements = round(linspace(10, 1000, 12));
times1 = zeros(numel(nUnique), numel(nElements));
times2 = zeros(numel(nUnique), numel(nElements));
times3 = zeros(numel(nUnique), numel(nElements));
times4 = zeros(numel(nUnique), numel(nElements));
times5 = zeros(numel(nUnique), numel(nElements));
for m = 1:numel(nUnique)
for n = 1:numel(nElements)
X = randi(nUnique(m), nElements(n), 1);
times1(m,n) = timeit(@()bsxfunApproach(X));
X = randi(nUnique(m), nElements(n), 1);
times2(m,n) = timeit(@()eyeApproach(X));
X = randi(nUnique(m), nElements(n), 1);
times3(m,n) = timeit(@()sub2indApproach(X));
X = randi(nUnique(m), nElements(n), 1);
times4(m,n) = timeit(@()sparseApproach(X));
X = randi(nUnique(m), nElements(n), 1);
times5(m,n) = timeit(@()sparseFullApproach(X));
end
end
colors = get(0, 'defaultaxescolororder');
figure;
surf(nElements, nUnique, times1 * 1000, 'FaceColor', colors(1,:), 'FaceAlpha', 0.5);
hold on
surf(nElements, nUnique, times2 * 1000, 'FaceColor', colors(2,:), 'FaceAlpha', 0.5);
surf(nElements, nUnique, times3 * 1000, 'FaceColor', colors(3,:), 'FaceAlpha', 0.5);
surf(nElements, nUnique, times4 * 1000, 'FaceColor', colors(4,:), 'FaceAlpha', 0.5);
surf(nElements, nUnique, times5 * 1000, 'FaceColor', colors(5,:), 'FaceAlpha', 0.5);
view([46.1000 34.8000])
grid on
xlabel('Elements')
ylabel('Unique Values')
zlabel('Execution Time (ms)')
legend({'bsxfun', 'eye', 'sub2ind', 'sparse', 'full(sparse)'}, 'Location', 'Northwest')
end
function Y = bsxfunApproach(X)
Y = bsxfun(@eq, X(:), 1:max(X));
end
function Y = eyeApproach(X)
tmp = eye(max(X));
Y = tmp(X, :);
end
function Y = sub2indApproach(X)
LinearIndices = sub2ind([length(X),max(X)], [1:length(X)]', X);
Y = zeros(length(X), max(X));
Y(LinearIndices) = 1;
end
function Y = sparseApproach(X)
Y = sparse(1:numel(X), X,1);
end
function Y = sparseFullApproach(X)
Y = full(sparse(1:numel(X), X,1));
end
如果你需要一個非稀疏輸出bsxfun
表現最好,但如果你能使用sparse
矩陣(無需轉換到全矩陣),那麼這是最快和最內存高效的選擇。
這是爲什麼?他只是做一個簡單的索引操作 –
哦,好的,你在談論眼圖矩陣的大小。 –
@suever我認爲你的意思是內存使用量增長的二次方,因爲eye(max(X))佔用最大(X)^ 2內存。指數內存使用率將是c^max(X) – osipov
我覺得這是快特別是當矩陣尺寸長:
Y = sparse(1:numel(X), X,1);
或
Y = full(sparse(1:numel(X), X,1));
萬一有人找2D情況下(我是) :
X = [2 1; ...
3 3; ...
2 4]
Y = zeros(3,2,4)
for i = 1:4
Y(:,:,i) = ind2sub(X,X==i)
end
沿着第三維給出一個單熱編碼矩陣。
你嘗試過什麼嗎? –
是的,我一直嘗試不同的方法與sub2ind,但最終使用索引到身份矩陣如下。 – osipov