开发者

Split an array in MATLAB

开发者 https://www.devze.com 2023-03-16 14:33 出处:网络
I have an array of integer numbers, and I want to 开发者_StackOverflow社区split this array where 0 comes and a function that give me points of split.

I have an array of integer numbers, and I want to 开发者_StackOverflow社区split this array where 0 comes and a function that give me points of split.

Example: Array : 0 0 0 1 2 4 5 6 6 0 0 0 0 0 22 4 5 6 6 0 0 0 4 4 0

The function must return these numbers:

[ 3 10 ;14 20 ;22 25 ]

These numbers are index of start and end of nonzero numbers.


Here's a simple vectorized solution using the functions DIFF and FIND:

>> array = [0 0 0 1 2 4 5 6 6 0 0 0 0 0 22 4 5 6 6 0 0 0 4 4 0];  %# Sample array
>> edgeArray = diff([0; (array(:) ~= 0); 0]);
>> indices = [find(edgeArray > 0)-1 find(edgeArray < 0)]

indices =

     3    10
    14    20
    22    25

The above code works by first creating a column array with ones indicating non-zero elements, padding this array with zeroes (in case any of the non-zero spans extend to the array edges), and taking the element-wise differences. This gives a vector edgeArray with 1 indicating the start of a non-zero span and -1 indicating the end of a non-zero span. Then the function FIND is used to get the indices of the starts and ends.

One side note/nitpick: these aren't the indices of the starts and ends of the non-zero spans like you say. They are technically the indices just before the starts and just after the ends of the non-zero spans. You may actually want the following instead:

>> indices = [find(edgeArray > 0) find(edgeArray < 0)-1]

indices =

     4     9
    15    19
    23    24


Try this

a = [0 0 0 1 2 4 5 6 6 0 0 0 0 0 22 4 5 6 6 0 0 0 4 4 0];

%#Places where value was zero and then became non-zero
logicalOn = a(1:end-1)==0 & a(2:end)~=0;

%#Places where value was non-zero and then became zero
logicalOff = a(1:end-1)~=0 & a(2:end)==0;

%#Build a matrix to store the results
M = zeros(sum(logicalOn),2);

%#Indices where value was zero and then became non-zero
[~,indOn] = find(logicalOn);

%#Indices where value was non-zero and then became zero
[~,indOff] = find(logicalOff);

%#We're looking for the zero AFTER the transition happened
indOff = indOff + 1;

%#Fill the matrix with results
M(:,1) = indOn(:);
M(:,2) = indOff(:);

%#Display result
disp(M);


On the theme, but with a slight variation:

>>> a= [0 0 0 1 2 4 5 6 6 0 0 0 0 0 22 4 5 6 6 0 0 0 4 4 0];
>>> adjust= [0 1]';
>>> tmp= reshape(find([0 diff(a== 0)])', 2, [])
tmp =
    4   15   23
   10   20   25
>>> indices= (tmp- repmat(adjust, 1, size(tmp, 2)))'
indices =
    4    9
   15   19
   23   24

As gnovice already pointed out on the positional semantics related to indices, I'll just add that, with this solution, various schemes can be handled very straightforward manner, when calculating indices. Thus, for your request:

>>> adjust= [1 0]';
>>> tmp= reshape(find([0 diff(a== 0)])', 2, []);
>>> indices= (tmp- repmat(adjust, 1, size(tmp, 2)))'
indices =
    3   10
   14   20
   22   25
0

精彩评论

暂无评论...
验证码 换一张
取 消