使用基于索引MATLAB的元素填充单元格数组

nik*_*nik 1 matlab cell-array

我有一个*m单元阵列Cell_In:

a b
* *
* *
c *
* d
* *
* f
Run Code Online (Sandbox Code Playgroud)

* - >表示空字符串('').这就是我需要的:

a b
a b
a b
c b
c d
c d
c f
Run Code Online (Sandbox Code Playgroud)

对于特定列,我需要用前一个非空单元格填充空单元格,直到找到另一个非空单元格.以下是我写的代码.

b = ~cellfun(@isempty,a);
c = [find(b(:,1) == 1);size(a,1)+1]; e = diff(c);
d = [find(b(:,2) == 1);size(a,1)+1]; f = diff(d);
s1 = ''; s2 = '';
for i = 1:length(e)
    s1 = [s1,repmat(a(c(i),1),1,e(i))];
end

for i = 1:length(f)
    s2 = [s2,repmat(a(d(i),2),1,f(i))];
end
Cell_Out = [s1',s2'];
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我想知道最好的解决方案?

Div*_*kar 5

假设A是输入单元阵列,这里可能有两种方法.

方法#1

%// Initlialize output array
Aout = cell(size(A));

for k = 1:size(A,2)

    %// Select one column
    Ak = A(:,k);

    %// Logical array with size of Ak and ones at places with non-empty strings
    pos = cellfun(@(x) ~isempty(x), Ak);

    %// Find unique strings and find indices for all places in that column
    %// with respect to those unique strings
    [unq_str,~,str_idx] = unique(Ak,'stable');

    %// Perform cumsum on pos to get an array with a "stepped" array that
    %// steps up at each non-empty string position.
    %// Then replace each stepping number with the string IDs
    idx = changem(cumsum(pos),str_idx(pos),1:sum(pos));

    %// Index into each column with those replaced IDs for the final output
    Aout(:,k) = unq_str(idx);
end
Run Code Online (Sandbox Code Playgroud)

随着输入稍微改变以便更加积极地测试解决方案代码,我们在代码运行之后 -

A = 
    'a'    'b'
    ''     '' 
    ''     'a'
    'c'    '' 
    ''     'd'
    'a'    '' 
    ''     'f'
    'c'    'a'

Aout = 
    'a'    'b'
    'a'    'b'
    'a'    'a'
    'c'    'a'
    'c'    'd'
    'a'    'd'
    'a'    'f'
    'c'    'a'
Run Code Online (Sandbox Code Playgroud)

方法#2 [紧凑,可能更高效]

您可以将输入单元阵列重新整形为单个圆柱形单元阵列,因此您无需循环遍历单元阵列的列,这可能会导致更高效和紧凑的代码 -

%// Reshape all cells into a single columned cell array
A1 = A(:);

%// Rest of the code borrowed from previous approach with reshaping added
%// at the end to bring the output back to the size of input array
pos = ~cellfun('isempty', A1);
[unq_str,~,str_idx] = unique(A1,'stable');
Aout =  reshape(unq_str(changem(cumsum(pos),str_idx(pos),1:sum(pos))),size(A));
Run Code Online (Sandbox Code Playgroud)

奖金:定制实施 changem

前面列出的代码使用了changem这些需求Mapping Toolbox.所以,如果你有它,这里是它的定制版本,用bsxfun和实现,并且max只是这里发布的早期解决方案代码的精美版本.这里是自定义功能代码 -

%// CHANGEM_CUSTOM  Home-cooked vesion of CHANGEM with MAX, BSXFUN
function A  = changem_custom(A,newvals,oldvals)

[valid,id] = max(bsxfun(@eq,A(:),oldvals(:).'),[],2); %//'
A(valid) = newvals(id(valid));

return;
Run Code Online (Sandbox Code Playgroud)

因此,要使用此自定义函数进行替换changem,只需在早期代码中替换函数调用名称即可.