cell to matrix matching / map / cellOperations (MATLAB) - matlab

I cannot find the string equivalent of the finalAnswer using the data below. Please, I cannot use if/for loops! A final answer is preferred with each element as an array (i.e. the format of mainData)
mainData = {'IBM' [201] [1] ;
'GE' [403] [1] ;
'MSFT' [502] [3] ;
'GM' [101] [2] } ;
finalAns = [ 101 2 0.5; 403 1 0.6 ] ;
%% I tried doing this ->
temp = cell2mat(mainData(:,[2 3])) ;
tf = ismember(temp, finalAns(:,[1 2],'rows') ;
secIDs = mainData(tf) ;

In order to get the entries in each row of mainData that match those in finalAns (based on the last two columns of mainData and the first two columns of finalAns) and to get them in the same order that they appear in finalAns and with the last column of finalAns appended, you can do this:
>> temp = cell2mat(mainData(:,2:3));
>> [isThere,index] = ismember(finalAns(:,1:2),temp,'rows');
>> output = [mainData(index(isThere),:) num2cell(finalAns(isThere,3))]
output =
'GM' [101] [2] [0.5000]
'GE' [403] [1] [0.6000]
The output is a 2-by-4 cell array with each value in a separate cell. If you want the last three columns to be collected in a vector, you can replace the calculation of output above with this:
>> temp = [temp(index(isThere),:) finalAns(isThere,3)];
>> output = [mainData(index(isThere),1) num2cell(temp,2)]
output =
'GM' [1x3 double]
'GE' [1x3 double]
Note that now you have a 2-by-2 cell array where cells in the second column contain 1-by-3 double arrays.

Related

Creating cells in Matlab

I want to create cells in matlab like the following:
Q{1,1,1}=1;
Q{1,1,2}=1;
Q{2,2,1}=1;
Q{2,1,2}=1;
However, I do not want to create this manually. In my application I have some vectors, one of which can be: x=[1 2 3 4]
And with this vector x I want to create
P{1,2,3,4}=1
So the vector x kind of dictates the coordinates of the cell (sorry for bad english).
Since I dont know the length of the vector (it can change from case to case) I cannot do this:
P{x(1,1),x(1,2),x(1,3),x(1,4)}=1;
What can I do here?
EDIT: I put the cells content with number "one" just for an example. The content of cell its gonna be linear matrix variable generated by the function sdpvar from the yalmip toolbox.
First, if you only have numeric content perhaps a matrix is better then a cell.
To populate the spaces within a cell with a certain input you could do the following:
x = [1 2 3 4];
P(x) = {1}
P =
[1] [1] [1] [1]
This also works when a index is skipped
x = [1 2 4 5]
P(x) = {1}
P =
[1] [1] [] [1] [1]
To create your Q cell you should preallocate it to get the correct size, then you could use sub2ind to point out correct indexes
Q = cell(2,2,2)
% To populate all with 1
Q(:) = {1}
Q(:,:,1) =
[1] [1]
[1] [1]
Q(:,:,2) =
[1] [1]
[1] [1]
% To populate only a certain indexes
idx = sub2ind( size(Q), [1 1 2 2], [1 1 2 1], [1 2 1 2]);
Q(idx) = {1}
Q(:,:,1) =
[1] []
[] [1]
Q(:,:,2) =
[1] []
[1] []
I am not sure you can do that without resorting to eval:
>>> x=[1,2,3,4];
>>> value=1 % or whatever you need here
>>> cmd=sprintf('%s%s%s','P{', strjoin(arrayfun(#(a) num2str(a),x,'UniformOutput',false),','), '}=value')
cmd = P{1,2,3,4}=1
>>> eval(cmd)
P = {1x2x3x4 Cell Array}
>>> P{1,2,3,4}
ans = 1
>>>

In Matlab, How to eliminate empty columns from the cell array?

So in 3 X 18 cell array, 7 columns are empty and I need a new cell array that's 3 X 11. Any suggestions without going for looping ?
Let's consider the following cell array. Its second column consists only of [], so it should be removed.
>> c = {1 , [], 'a'; 2, [], []; 3, [], 'bc'}
c =
[1] [] 'a'
[2] [] []
[3] [] 'bc'
You can compute a logical index to tell which columns should be kept and then use it to obtain the result:
>> keep = any(~cellfun('isempty',c), 1); %// keep columns that don't only contain []
keep =
1 0 1 %// column 2 should be removed
>> result = c(:,keep)
result =
[1] 'a'
[2] []
[3] 'bc'
How it works:
cellfun('isempty' ,c) is a matrix the same size as c. It contains 1 at entry (m,n) if and only if c{m,n} is empty.
~cellfun('isempty' ,c) is the logical negation of the above, so it contains 1 where c is not empty.
any(~cellfun('isempty' ,c), 1) applies any to each column of the above. So it's a row vector such that its m-th entry equals 1 if any of the cells of c in that column are non-empty, and 0 otherwise.
The above is used as a logical index to select the desired columns of c.
Use cellfun to detect elements, then from that find columns with empty elements and delete those:
cellarray(:, any(cellfun(#isempty, cellarray), 1)) = [];
If instead you'd like to keep columns with at least one non-empty element, use all instead of any.
For example:
>> cellarray = {1 2 ,[], 4;[], 5, [], 3}
[1] [2] [] [4]
[] [5] [] [3]
>> cellarray(:,any(cellfun(#isempty, cellarray), 1))=[]
cellarray =
[2] [4]
[5] [3]

How to calculate the number of rows in a Cell array in MATLAB

I want to calculate the number of rows in a Cell array in MATLAB.
I use the code below to count the number of columns in a cell array but I do not know its way for counting the rows.
filledCells = ~cellfun(#isempty,a);
columns = sum(filledCells,2)
As an example, i've got x as a cell array:
x = [5] [1x8 double] [5]
This cell array has one row and three columns. I need a code to calculate the number of rows equal to "1" , but I did not find a way to calculate it.
I used most of ideas but it did not work then with the help of what herohuyongtao said i reach to this idea which worked properly
[nr,nc]=size(x)
Which nr is the number of rows
thanks all of you.
A slightly more general approach: works for rows or columns, and takes into account the size of each cell:
dim = 1; %// 1 for rows, 2 for columns
result = sum(cellfun(#(c) size(c,dim), a), dim);
Example:
>> a = {1, [2 3], []; 4, [], 5}
a =
[1] [1x2 double] []
[4] [] [5]
>> dim = 1;
gives
>> result = sum(cellfun(#(c) size(c,dim), a), dim)
result =
2 1 1
Try
%% "a" is the cell array, total num of rows will be saved in "rows"
num = length(a); % num of objects in "a" - big rows
rows = 0;
for i=1:num
[r c] = size(C{i})
rows = rows+r;
end
The simplest way to achieve this would be to get the first dimension of the size.
rowCount = size(x,1)

Deleting rows from a Matlab cell matrix which match a given pattern

I have a cell matrix with two columns (no headers). Column one contains ticker symbols, e.g AAPL, GS etc. Column two contains either 0 or 1.
How can I delete all rows that contain '1' in column 2? Then how can I get an output of the remaining ticker symbols separately in a different m file?
Help please!
Does this do what you need?
>> a = {'AAPL', 1; 'MSFT', 0; 'GOOG' 1; 'IBM', 0} % Make some data like the OP's
a =
'AAPL' [1]
'MSFT' [0]
'GOOG' [1]
'IBM' [0]
>> toDelete = cell2mat(a(:,2)) == 1; % Extract which rows have a 1 in column 2
>> a(toDelete,:) = []; % Delete those rows
>> remainingTickers = a(:,1) % Extract column 1 from the remaining rows
remainingTickers =
'MSFT'
'IBM'

Sorting a cell array

I want to sort the rows according to their second entries, i.e. by second column. Each entry of the second column is an array chars(representing a time stamp). There also might be missing values, i.e. the entry in the second column can be []. How do I do this?
you need to use the sortrows() function
if the matrix you wanted to sort is A then use
sorted_matrix = sortrows(A,2);
http://www.mathworks.com/help/techdoc/ref/sortrows.html
I would first convert the time stamps from strings to numeric values using the function DATENUM. Then you will want to replace the contents of the empty cells with a place holder, like NaN. The you can use the function SORTROWS to sort based on the second column. Here is an example:
>> mat = {1 '1/1/10' 3; 4 [] 6; 7 '1/1/09' 9} %# Sample cell array
mat =
[1] '1/1/10' [3]
[4] [] [6]
[7] '1/1/09' [9]
>> validIndex = ~cellfun('isempty',mat(:,2)); %# Find non-empty indices
>> mat(validIndex,2) = num2cell(datenum(mat(validIndex,2))); %# Convert dates
>> mat(~validIndex,2) = {NaN}; %# Replace empty cells with NaN
>> mat = sortrows(mat,2) %# Sort based on the second column
mat =
[7] [733774] [9]
[1] [734139] [3]
[4] [ NaN] [6]
The NaN values will be sorted to the bottom in this case.