我有一个包含三种不同类型元素的单元格数组(11000x500)
。
1)非零双打
2)零
3)空单元
我想在两个零之间找到所有非零数字的出现。
E.g。 A = {123 13232 132 0 56 0 12 0 0 [] [] []};
我需要以下输出
out = logical([0 0 0 0 1 0 1 0 0 0 0 0]);
我使用了cellfun
和isequal
这样的
out = cellfun(@(c)(~isequal(c,0)), A);
并获得了以下输出
out = logical([1 1 1 0 1 0 1 0 0 1 1 1]);
我需要帮助才能执行下一步,我可以忽略连续的1's
并且只接受' 1'在两个0's
之间
有人可以帮帮我吗?
谢谢!
答案 0 :(得分:3)
以下是使用out
执行此操作(以及其他操作二进制数据)的快速方法:
out = logical([1 1 1 0 1 0 1 0 0 1 1 1]);
d = diff([out(1) out]); % find all switches between 1 to 0 or 0 to 1
len = 1:length(out); % make a list of all indices in 'out'
idx = [len(d~=0)-1 length(out)]; % the index of the end each group
counts = [idx(1) diff(idx)]; % the number of elements in the group
elements = out(idx); % the type of element (0 or 1)
singles = idx(counts==1 & elements==1)
你会得到:
singles =
5 7
从这里你可以继续并根据需要创建输出:
out = false(size(out)); % create an output vector
out(singles) = true % fill with '1' by singles
你得到:
out =
0 0 0 0 1 0 1 0 0 0 0 0
答案 1 :(得分:2)
您可以使用conv
查找包含0个邻居的元素(请注意~
已从isequal
中删除):
out = cellfun(@(c)(isequal(c,0)), A); % find 0 elements
out = double(out); % cast to double for conv
% elements that have more than one 0 neighbor
between0 = conv(out, [1 -1 1], 'same') > 1;
between0 =
0 0 0 0 1 0 1 0 0 0 0 0
(纠正了卷积内核以修复@TasosPapastylianou发现的错误,其中3个连续的零将导致True。)
如果你想要一个逻辑矢量那就是。如果您想要索引,只需添加find
:
between0 = find(conv(out, [1 -1 1], 'same') > 1);
between0 =
5 7
答案 2 :(得分:1)
另一个解决方案,这完全避免了你的初始逻辑矩阵,但我认为你不需要它。
A = {123 13232 132 0 56 0 12 0 0 [] [] []};
N = length(A);
B = A; % helper array
for I = 1 : N
if isempty (B{I}), B{I} = nan; end; % convert empty cells to nans
end
B = [nan, B{:}, nan]; % pad, and collect into array
C = zeros (1, N); % preallocate your answer array
for I = 1 : N;
if ~any (isnan (B(I:I+2))) && isequal (logical (B(I:I+2)), logical ([0,1,0]))
C(I) = 1;
end
end
C = logical(C)
C =
0 0 0 0 1 0 1 0 0 0 0 0