如何在matlab中的单元格数组中的两个零之间找到一个非零数
How to find a non-zero number between two zeros in a cell array in matlab
我有一个包含三种不同类型元素的元胞数组 (11000x500)
。
1) 非零双打
2) 零
3) 空单元格
我想找出两个零之间出现的所有非零数。
例如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
,只取两个 0's
之间的“1”
有人可以帮我解决这个问题吗?
谢谢!
这是使用 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
另一个解决方案,虽然这完全避免了您的初始逻辑矩阵,但我认为您不需要它。
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
您可以使用 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
我有一个包含三种不同类型元素的元胞数组 (11000x500)
。
1) 非零双打
2) 零
3) 空单元格
我想找出两个零之间出现的所有非零数。
例如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
,只取两个 0's
有人可以帮我解决这个问题吗?
谢谢!
这是使用 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
另一个解决方案,虽然这完全避免了您的初始逻辑矩阵,但我认为您不需要它。
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
您可以使用 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