How to remove a row from a matrix inside a cell array - arrays

I have a cell array (A) with size of 400 x 1 and each cell of this array includes a matrix with size 9 x 4. As such, it looks like this:
A={[9x4 double];[9x4 double];...;[9x4 double]};
Now, I want to remove the zero rows from these sub matrices and then obtain a new A cell array called A_new where its sub matrices don't have any zero rows like this:
A_new={[5x4 double];[7x4 double];...;[4x4 double]};
By my below code, I can find the index of rows which are not zero but I couldn't create my cell array like I mentioned above. This is my written code and for the bold part, I have a problem and I couldn't solve it.
for i=1:A_Length
[row,col]=find(A{i,1});
out=[row col];
NNZ_row=unique(row);
Length_NNZ= length(NNZ_row);
for j=1:Length_NNZ
**A_NonZero{i,1}= ??????????**
end
end

What I would do is take each cell, then use all on the opposite of the matrix over all of the columns in each row to determine which rows contain all zeroes. Once you do this, use these locations and remove those rows from this matrix and save this to your new matrix.
As such, do this:
A_new = cell(1,numel(A));
for i=1:numel(A)
mat = A{i};
ind = all(~mat, 2);
A_new{i} = mat(~ind,:);
end
The first line of code creates a new cell array that is the same size as A. Next, for each element in A, extract the matrix at each cell location, use all on the opposite of this matrix to find those elements that we need to keep, then save this new matrix into the corresponding location in A_new.
If you want to do this in a single line of code, use cellfun:
A_new = cellfun(#(x) x(~all(~x,2),:), A, 'uni', 0);
The first argument to cellfun is an anonymous function that performs what the for loop was doing. We find those rows that contain all zeroes and use those to remove the rows in each matrix in the cell array. The second argument is the matrix we want to operate on, which is A. The 'uni' and 0 flags are important because the outputs are not single values but matrices, and so the output of this function will be a cell array that is the same size as A where each element is the matrix for those corresponding locations in A with the zero rows removed.

You should use a combination of cellfun and any:
A_new = cellfun(#(x) x(any(x~=0,2),:), A, 'UniformOutput', false);
should do the trick.

Related

Calculating standard deviation on data stored in a cell array of cell arrays

I have a cell array A Mx3 in size where each entry contains a further cell-array Nx1 in size, for example when M=9 and N=5:
All data contained within in any given cell array is in vector format and of equal length. For example, A{1,1} contains 5 vectors 1x93 in size whilst A{1,2} contains 5 vectors 1x100 in size:
I wish to carry out this procedure on each of the 27 cells:
B = transpose(cell2mat(A{1,1}));
B = sort(B);
C = std(B,0,2); %Calculate standard deviation
Ultimately, the desired outcome would be, for the above example, 27 columns (9x3) containing the standard deviation results (padded with 0 or NaNs to handle differing lengths) printed in the order A{1,1}, A{1,2}, A{1,3}, A{2,1}, A{2,2}, A{2,3} and so forth.
I can do this by wrapping the above code into a loop to iterate over each one of the 27 cells in the correct order however, I was wondering if there was a clever cellfun or more succinct method to accomplish this particularly without the use of a loop?
You should probably realize that cellfun is essentially a glorified for loop over cells. There's simply extra error checking and all that to ensure that the whole thing works. In any case, yes it's possible to do what you're asking in a single cellfun call. Note that I am simply going to apply the same logic as you would have in a for loop with cellfun. Also note that because you're using cell arrays, you have no choice but to iterate over the entire master cell array. However, what you'll want to do is pad each resulting column vector in each output in the final cell array so that they all share the same length. We can do that with another two cellfun calls - one to determine the largest vector length and another to perform the padding operation.
Something like this could work:
% Step #1 - Sort the vectors in each cell array, then find row-wise std
B = cellfun(#(x) std(sort(cell2mat(x).'), 0, 2), A, 'un', 0);
% Step #2 - Determine the largest length vector and pad
sizes = cellfun(#numel, B);
B = cellfun(#(x) [x; nan(max(sizes(:)) - numel(x), 1)], B, 'un', 0);
The first line of code takes each element in A, converts each cell element into a N x 5 column matrix (i.e. cell2mat(x).'), we then sort each column individually with sort, then take the standard deviation row-wise. Because the output is ultimately a vector, we must make sure that the 'UniformOutput' flag is 0, or 'un=0'. Once we complete the standard deviation calculation, we determine the total number of elements for each resulting column vector for all cell elements, determine the largest size then use another cellfun call to pad these vectors so they all match the same size.
To finally get your desired output, you need to transpose the cell array, then unroll the elements in column major order. Remember that MATLAB accesses things in column major, so a common trick to get things in row-major (what you want) as opposed to column major is to first transpose, then unroll in column-major fashion to perform a row-major readout. Doing this in one line is tricky, so you'll need to not only transpose the cell array, you must use reshape to ensure that the elements are read out in row major format, but then ensuring that the result is placed in a row of cells, then call cell2mat so you can piece these vectors together. The final result should be a 27 column matrix where we have pieced all of these vectors together in a single row-wise fashion:
C = cell2mat(reshape(B.', 1, []));

Search elements of matrix in another cell in matlab

I have a column matrix and a cell array which has two columns.The first column has 1x2 doubles and the second column has 1x1 doubles.
For example
columnMatrix = [1;5];
cellArray = {[1,8],[10];[8,1],[20];[4,6],[80];[3,5],[40];[14,16],[85];[5,10],[36]};
I would like to search each element of columnMatrix in cellArray(:,1) and then return its corresponding value in cellArray(:,2)
For example the output has to be like this
newCell = {[1],[10,20];[5],[40,36]};
I tried using the ismember function in this way
[~,idx] = ismember(cell2mat(cellArray(:,1)),columnMatrix (: , 1));
This returns all the indices which have the searched element but they are in two seperate columns and I can not perform any other logical operation to get the corresponding second column entry.
Is there some way this operation can be achieved? Could some one please help?
Thanks
First of all, convert first column of cellArray to a matrix so it would be easier to search values in. Then iterate over columnMatrix values (e.g. using arrayfun, but you could also use for loop), find rows that match (any across columns) and select corresponding values from the second column of cellArray, converting to numeric array ([cellArray{...,2}]). Finally, append the columnMatrix as the first column of the resulting cell array:
columnMatrix = [1;5]; cellArray = {[1,8],[10];[8,1],[20];[4,6],[80];[3,5],[40];[14,16],[85];[5,10],[36]};
mat = cell2mat(cellArray(:,1));
values = arrayfun(#(x) [cellArray{any(mat==x,2),2}], columnMatrix, 'uni', false);
result = [num2cell(columnMatrix), values];

MATLAB indexing all the cells in a cell array of matrices

I have a cell array where each cell contains a matrix (different sizes). I would like, e.g., to take all the second columns of the matrices providing a command like:
aux = cArray{:}(:,2)
The result I'd like to obtain is a cell array where each cell contains the second column of the original matrix, but the command doesn't work (and I can even see why, since the output of cArray{:} is not a matrix ... )
Is there a compact command to get what I want instead of a cycle filling up the cell array ?
The reason why it doesn't work is that indexing a cell array with {:} produces a comma-separated list, which is not indexable anymore. You can view it as the "unwrapped" contents of the cell array separated by commas.
You can achieve what you want with cellfun:
result = cellfun(#(x) x(:,2), cArray, 'uniformoutput', false);
This applies the anonymous function #(x) x(:,2) to each cell's contents, and packs the results in a cell array.

Cell array to matrix conversion in matlab

I would like to covert three <1xN cell> (A, B and C) into a single Nx3 matrix. Could someone help me with this?
C={{1xN}; {1xN}; {1xN}};
where each N is a number in single quotes, e.g.
C = {{'123123' ,'12324', ....N times}; {'123123', '12324', ....N times}; {'123123', '12324' ,....N times}}
Since a couple of them mentioned about the ridiculous input, this is the reason for having it in the above form.
The three nested array of cells are the results of a regexp where my string and expression are both strings. Therefore I have the output of regexp as three cell arrays of row vectors.
For e.g.
node_ids=regexp(nodes,'(?<=node id=")\d*','match');
I can use cat function and then use a str2double for all three cell arrays and finally form a matrix by cell2mat.
For e.g.
node_ids=cat(1,node_ids{:});node_ids=str2double(node_ids);
But this takes more time and has more LOC.
My question is can it be done with fewer lines of code?
I tried using the cat function but keep getting this error:
Cannot support cell arrays containing cell arrays or objects.
Your input data is pretty bad.... why are you using a nested array of cells where each element is a string?
In any case, assuming C is your original input data, do this:
C = {{'123123' '12324'}; {'123123' '12324'}; {'123123' '12324'}};
out = cellfun(#(x) cellfun(#str2num, x, 'uni', 0), C, 'uni', 0);
out = cell2mat(cellfun(#cell2mat, out, 'uni', 0));
First line is some dummy data. Next line first goes through every nested cell element over your cell array and converts the strings into numbers. However, these are still in cell arrays. As such, the next line converts each cell array in the nested cell into a matrix, then we merge all of the cells together into one final matrix.
We get:
>> out
out =
123123 12324
123123 12324
123123 12324

Matlab Convolution Array with vector row by row - Galois Field(2)

Let's say I have array A(n,k) and vector b(1,4). Matrix and vector's context are on Galois Field (2).
Is there any way to convolute each row of A with vector b without for loop?
For example if A is of size (4,5) then the command should do the following:
conv(A(1,:),b)
conv(A(2,:),b)
conv(A(3,:),b)
conv(A(4,:),b)
Any ideas?
You can first convert A to a cell array and then use cellfun to apply your function to every element of the cell array, such as:
cellA = num2cell(A, 2) % creates a cell array where each element is a row of A
result = cellfun(#(row)(conv(row, b)), cellA);
Here #(row)(conv(row, b)) is an anonymous function that takes one element of the cell array and applies your conv function to it and your b vector

Resources