Extracting a specific element from each cell withi

2019-02-24 23:07发布

问题:

I have a cell array A of size 10x10 (say). Each cell in turn contains a 5x20 matrix. I want to select (i,j) element from each cell, where (i,j) are indices within a loop. I can run 4 for loops and easily get the answer. It may even be faster as it has been discussed many times that loops could be faster than cellfun, structfun etc.

Still, is there any solution using cellfun which I can use in a loop over (i,j) and extract (i,j) element in each cell? I tried writing a function which will act as handle to cellfun but I couldn't access two-leves down i.e. A{eachCellRow,eachCellCol}(i,j).

Example: If A={[1 2;5 6], [3 4; 6 7]; [3 4; 6 7], [9 8; 5 6]};

Then for i=1, j=1 and i=2, j=1 output should be:

B=[1 3; 3 9] and B=[5 6; 6 5]

回答1:

CELL2MAT gets all the data from a cell array that consists of numeric data only, into a numeric array. So, that helped us here. For your original problem, try this -

celldim_i = 10;
celldim_j = 10;

block_size_i = 5;
block_size_j = 20;

search_i = i; %// Edit to your i
search_j = j; %// Edit to your j

A_mat = cell2mat(A);
out = A_mat(search_i+block_size_i*(0:celldim_i-1),search_j+block_size_j*(0:celldim_j-1))


回答2:

The easy to use cellfun one-liner would be:

ii = 2;
jj = 1;
A = {[1 2;5 6], [3 4; 6 7]; [3 4; 6 7], [9 8; 5 6]};

B = cell2mat( cellfun( @(x) x(ii,jj), A, 'uni', 0) )

gives:

B =

     5     6
     6     5

Advantage over Divakar's Solution: it works also for inconsistent matrix sizes in A.

And if you want to avoid also the outer loop, another fancy two-liner:

dim = [2 2];
[II, JJ] = meshgrid( 1:dim(1), 1:dim(2) );

C = cellfun( @(y) ...
    { cell2mat( cellfun( @(x) x( real(y), imag(y) ), A, 'uni', 0) ) },...
      num2cell( II(:)+1i*JJ(:) ))

gives:

>> celldisp(C)

C{1} =            % ii = 1 , jj = 1

     1     3
     3     9



C{2} =            % ii = 1 , jj = 2

     2     4
     4     8



C{3} =            % ii = 2 , jj = 1

     5     6
     6     5



C{4} =            % ii = 2 , jj = 2

     6     7
     7     6


回答3:

If memory is not an issue, you can concat all matrices along a third dim; and then indexing is very easy:

%// Example data
A = {[1 2;5 6], [3 4; 6 7]; [3 4; 6 7], [9 8; 5 6]};
ii = 2;
jj = 1;

%// Compute the result B
A2 = cat(3,A{:}); %// concat along third dim
B = reshape(A2(ii,jj,:),size(A{1})); %// index A2 and reshape