2015-01-13 14 views
5

Tôi muốn chỉ định giá trị số tích lũy cho các lần chạy tuần tự trong một vectơ nhị phân. Những gì tôi có làGán số tuần tự cho các số chạy

x = [0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 0], 

và những gì tôi muốn là

y = [1 2 3 1 2 1 1 2 3 1 1 1 2 3 4 5 6]. 

Các giải pháp sử dụng số tiền/cumsum/độc đáo/tìm loạt các chức năng ám chỉ tôi. Mọi sự trợ giúp sẽ rất được trân trọng.

Trả lời

6

Đây là một cách:

a = arrayfun(@(x)(1:x), diff(find([1,diff(x),1])), 'uni', 0); 
[a{:}] 

Ý tưởng là để tạo ra một danh sách các 'dài chạy', tức là [3,2,1,3,1,1,6] trong trường hợp của bạn, sau đó chỉ cần nối một loạt các vectơ mà đếm đến mỗi giá trị trong danh sách đó , tức là cat(2, 1:3, 1:2, 1:1, 1:3.... Tôi sử dụng arrayfun làm lối tắt để đăng ký lại toán tử : và sau đó sử dụng danh sách được phân tách bằng dấu phẩy {:} trả về dưới dạng lối tắt cho nối.

+0

đẹp một lót, đặc biệt là với các trick vào ':' – Bentoy13

+0

Vâng phát hiện trên ứng dụng ' '@ (x) 1: x'' trên runlength en mã hóa! – Nras

+0

wow. tuyệt quá! Một lót của bạn rất mát mẻ (và phức tạp) đôi khi họ cho tôi một nhức đầu! Công việc tốt. –

6

(Không phải là một one-liner, than ôi ...):

F = find(diff(x))+1; 
y = ones(size(x)); 
y(F) = y(F)-diff([1,F]); 
y = cumsum(y); 

Thứ nhất, tất cả các vị trí trong x nơi có sự thay đổi; sau đó xây dựng một vectơ 1, trong đó bạn trừ đi chiều dài của mỗi đoạn liên tục. Cuối cùng, lấy cumsum của nó.

+0

Đây là một cách tiếp cận thông minh! – Dan

+0

Tôi cũng có những nghi phạm thông thường '' find'', '' diff'' và đặc biệt là '' cumsum'' trong đầu khi đọc câu hỏi. Điều này sẽ trông khá giống với cách tiếp cận của tôi (chưa tồn tại). – Nras

+0

Đây là loại giải pháp mà tôi đã có trong đầu - nhưng không thể làm việc được. Rất cám ơn @ Bentoy13. –

1

Tạo một ma trận sparse như vậy mà mỗi lần chạy là trên một cột khác nhau, và sau đó làm tổng tích lũy:

t = sparse(1:numel(x), cumsum([1 diff(x)~=0]), 1); 
y = nonzeros(cumsum(t).*t).'; 

Sử dụng accumarray với một chức năng tùy chỉnh để tạo ra mỗi mẫu tăng trong một tế bào khác nhau , và sau đó nối tất cả các ô:

y = accumarray(cumsum([1 diff(x)~=0]).', 1, [], @(x) {1:numel(x).'}); 
y = [y{:}]; 
+0

một giải pháp thay thế tôi sẽ không bao giờ xem xét. –

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