2011-11-08 85 views
13

Tôi có vectơ y có độ dài n. y (i) là một số nguyên trong 1 giờ. Có cách nào đơn giản hơn để chuyển đổi y thành một ma trận lôgic n x m, trong đó yy (i, j) = 1 nếu y (i) = j, nhưng 0 nếu không? Đây là cách tôi đã làm nó:Chuyển đổi vectơ thành ma trận logic?

% If m is known (m = 3 here), you could write it out all at once 
yy = [y == 1; y== 2; y == 3]; 
yy = reshape(yy, n, 3); 

hoặc

% if m is not known ahead of time 
yy = [ y == 1 ]; 
for i = 2:m; 
    yy = [ yy; y == i ]; 
end 
yy = reshape(yy, n, m); 
+0

Tôi tìm thấy một cách khác ... không chắc chắn nếu điều này là tốt hơn ... nhưng ít nhất nó phù hợp trên một dòng: yy = repmat (y, 1, m) == repmat (1: m, n, 1); – notrick

+1

'bsxfun' nằm trong số các hàm Matlab đa luồng. Do đó, nó có khả năng nhanh hơn các giải pháp của bạn. – Jonas

Trả lời

9

Bạn có thể sử dụng bsxfun cho điều này

yy = bsxfun(@eq,y(:),[1,2,3]) 

y được chuyển (nếu cần) cho một cột-vector, trong khi các vector khác là một vectơ hàng. bsxfun mở rộng ngầm các mảng m-by-1 và 1-by-n sao cho kết quả trở thành m-by-n.

5

Nếu n * m đủ lớn (và m, tự nó đủ lớn), bạn nên tạo yy làm ma trận thưa thớt. Vector y của bạn thực sự là một loại định dạng ma trận thưa thớt đặc biệt, nhưng chúng tôi có thể dịch nó thành định dạng ma trận thưa thớt tích hợp bằng cách thực hiện như sau.

yy = sparse(1:length(y), y, 1); 

Điều này sẽ giữ bộ nhớ của bạn thành O (n). Nó sẽ không làm cho bạn rất nhiều ưu đãi nếu bạn đang sử dụng yy cho rất nhiều lập chỉ mục. Nếu đúng như vậy, bạn nên sử dụng cấu trúc thưa thớt ban đầu của mình (ví dụ: y).

+0

+1 Chắc chắn là một lựa chọn tốt hơn để sử dụng 'bsxfun'. –

1

Một sửa đổi chút ít phương pháp của bạn:

% A n-dimensional vector y, with values in some range 1..m 
m = 4; 
n = 7; 
y = randi([1 m], n, 1); 

% Preallocating a n by m matrix of zeros 
nXm = zeros(n, m); 

% In each pass of this loop a single column of nXm is updated, where 
% for each column index j in nXm, if y(i) = j then nXm(i,j) = 1 
for j = 1:m; 
    nXm(:,j) = (y == j); 
end 
1

Từ Machine Learning trên Coursera:

yy = eye(m)(y, :) 

Điều này đòi hỏi rằng danh sách này là một loạt 1:m (như OP đã nêu). Để có danh sách không thường xuyên, chẳng hạn như [2 3 5], hãy làm điều này

yy = eye(m)(:, [2 3 5])(y, :) 

Lưu ý: không được thử nghiệm trên MATLAB.

+0

(Nhưng tôi vẫn thích cách của Jonas hơn, rất gọn gàng.) –

Các vấn đề liên quan