Extract a single column from a matrix - matlab

I have a matrix generated from the program written in Matlab something like this :
'A' 'B' 'C' 'D' 'E'
[ 4] [ 1] [ 0.9837] [ 0.9928] [0.9928]
[ 4] [ 1] [ 0.9995] [ 0.9887] [0.9995]
[ 4] [ 1] [ 0.9982] [ 0.9995] [0.9995]
[ 4] [ 1] [ 0.9959] [ 0.9982] [0.9887]
I am trying to extract the column 'D' without the header 'D'.
I can put into a temporary variable and then extract the column data. But I am wondering, if it could be done in a single step.
Thanks

If your variable is data, then data(2:end,4) should do it.
Edit:
For example:
>> data
data =
'A' 'B' 'C' 'D' 'E'
[4] [1] [0.9837] [0.9928] [0.9928]
[4] [1] [0.9995] [0.9887] [0.9995]
[4] [1] [0.9982] [0.9995] [0.9995]
[4] [1] [0.9959] [0.9982] [0.9887]
>> data(2:end,4) %Extract the data as a cell array
ans =
[0.9928]
[0.9887]
[0.9995]
[0.9982]
>> cell2mat(data(2:end,4)) %Convert to a numeric (typical) array
ans =
0.9928
0.9887
0.9995
0.9982

Related

Sub-titles for matrix columns in table

Here's my toy example:
t = table([1,2,3;4,5,6;7,8,9],[10,11,12;13,14,15;16,17,18]);
t.Properties.VariableNames = {'system1', 'system2'};
t.Properties.RowNames = {'obs1', 'obs2', 'obs3'};
I am wondering if it's possible to assign sub titles to the three columns of every variable, such as {'min', 'mean', 'max'}?
You can put those subtitles within the variables using a cell array like this:
t = table({'min', 'mean', 'max'; 1, 2, 3; 4, 5, 6; 7, 8, 9},...
{'min', 'mean', 'max'; 10, 11, 12; 13, 14, 15; 16, 17, 18});
t.Properties.VariableNames = {'system1', 'system2'};
t.Properties.RowNames = {'.','obs1', 'obs2', 'obs3'};
%if you don't like dot (.) as a row name, replace it with char(8203) to have nameless row
which will give:
t =
4×2 table
system1 system2
________________________ ________________________
. 'min' 'mean' 'max' 'min' 'mean' 'max'
obs1 [ 1] [ 2] [ 3] [ 10] [ 11] [ 12]
obs2 [ 4] [ 5] [ 6] [ 13] [ 14] [ 15]
obs3 [ 7] [ 8] [ 9] [ 16] [ 17] [ 18]
If you're looking for functional solution (e.g. t.system1.min) You can nest sub-tables for system1 and system2 with {'min', 'mean', 'max'} as Variable Names. Visually it won't be as useful as other solutions.
dat1 = [1,2,3;4,5,6;7,8,9];
dat2 = [10,11,12;13,14,15;16,17,18];
s1 = table(dat1(:,1),dat1(:,2),dat1(:,3));
s2 = table(dat2(:,1),dat2(:,2),dat2(:,3));
s1.Properties.VariableNames = {'min','mean','max'};
s1.Properties.RowNames = {'obs1', 'obs2', 'obs3'};
s2.Properties.VariableNames = {'min','mean','max'};
s2.Properties.RowNames = {'obs1', 'obs2', 'obs3'};
t = table(s1,s2);
t.Properties.VariableNames = {'system1', 'system2'};
t.Properties.RowNames = {'obs1', 'obs2', 'obs3'};

Combine 2 rows in a cell array

I have a number of rows in a cell array with lots of extra space at the end of the rows as such:
'a' 'b' 'c' 'd' [] [] [] [] []
'1' '2' '3' [] [] [] [] [] []
'w' 'x' 'y' 'z' [] [] [] [] []
I would like to copy the second row onto the end of the first row, as such:
'a' 'b' 'c' 'd' '1' '2' '3' [] []
'1' '2' '3' [] [] [] [] [] []
'w' 'x' 'y' 'z' [] [] [] [] []
Please note that the code given above is an arbitrary example to demonstrate what I wish to do. In reality I will include this functionality as a step in a more complex function.
I have tried searching for the first empty element in the cell array row, but for some reason isempty does not see them as empty. Is there an alternative method that someone could point me towards?
EDIT:
After the steps carried out above, the second row will be deleted, giving:
'a' 'b' 'c' 'd' '1' '2' '3' [] []
'w' 'x' 'y' 'z' [] [] [] [] []
Although the real cell array will have many more rows than 3.
I think this does what you want. I've denoted your cell array as c.
n1 = find(cellfun('isempty',c(1,:)), 1); %// first empty cell in row 1
n2 = find(cellfun('isempty',c(2,:)), 1); %// first empty cell in row 2
c(1,n1:n1+n2-2) = c(2,1:n2-1); %// copy the relevant part of row 2 onto row 1
This automatically extends your cell horizontally if the number of non-empty cells in row 2 exceeds the number of empty cells in row 1.
Example: input:
c = {'a' 'b' 'c' 'd' [] [] [] [] []
'1' '2' '3' [] [] [] [] [] []
'w' 'x' 'y' 'z' [] [] [] [] []}
Output:
c =
'a' 'b' 'c' 'd' '1' '2' '3' [] []
'1' '2' '3' [] [] [] [] [] []
'w' 'x' 'y' 'z' [] [] [] [] []
Here's one general approach that uses the efficient logical indexing to select the non-empty cells, single call to cellfun('isempty' and does automatic extension as talked about in Luis's solution -
C = {
'a' 'b' 'c' 'd' [] [] [] [] []
'1' '2' '3' [] [] [] [] [] []
'w' 'x' 'y' 'z' [] [] [] [] []} %// Input cell array
N = 2; %//Number of rows to process, starting from 2 until the number of rows in C
Ct = C'; %//'# Transpose input cell array, as collecting elements that way is easier
vals = Ct(~cellfun('isempty',Ct(:,1:N))); %//'# elements from selected row(s)
C(1,1:numel(vals)) = vals; %// Place the values into the first row
With N = 2 which is the case stated in the problem, output would be -
C =
'a' 'b' 'c' 'd' '1' '2' '3' [] []
'1' '2' '3' [] [] [] [] [] []
'w' 'x' 'y' 'z' [] [] [] [] []
With N = 3, you would copy the second and third rows at the end of the first row. Thus, the output would be -
C =
'a' 'b' 'c' 'd' '1' '2' '3' 'w' 'x' 'y' 'z'
'1' '2' '3' [] [] [] [] [] [] [] []
'w' 'x' 'y' 'z' [] [] [] [] [] [] []
and so on.

extracting data from excel to matlab

Suppose i have an excel file (data.xlsx) , which contains the following data.
Name age
Tom 43
Dick 24
Harry 32
Now i want to extract the data from it and make 2 cell array (or matrix) which shall contain
name = ['Tom' ; 'Dick';'Harry'] age = [43;24;32]
i have used xlsread(data.xlsx) , but its only extracting the numerical values ,but i want to obtain both as mentioned above . Please help me out
You have to use additional output arguments from xlread in order to get the text.
I created a dummy Excel file with your data and here is the output (nevermind about the NaNs):
[ndata, text, alldata] = xlsread('DummyExcel.xlsx')
ndata =
43
24
32
text =
'Name' 'Age'
'Tom' ''
'Dick' ''
'Harry' ''
alldata =
[NaN] 'Name' 'Age'
[NaN] 'Tom' [ 43]
[NaN] 'Dick' [ 24]
[NaN] 'Harry' [ 32]
Now if you use this:
text{2:end,1}
you get
ans =
Tom
ans =
Dick
ans =
Harry
You can use the function called importdata.
Example:
%Import Data
filename = 'yourfilename.xlsx';
delimiterIn = ' ';
headerlinesIn = 1;
A = importdata(filename,delimiterIn,headerlinesIn);
This will help to take both the text data and numerical data. Textdata will be under A.textdata and numerical data will be under A.data.

MATLAB : How to replace numbers in a single column of a cell with corresponding strings?

I have a 50000 * 2 cell with number contents. Now I want to replace the second column which has numbers ranging from 1 to 10 with corresponding strings like 'airplane' for 1, 'automobile' for 2 and so on. What is the most efficient method for this?
I tried first by splitting the second column content to a new cell classes1 and coverted it to strings and tried replacing by applying the code below :
classes1(strcmp('1',classes1))={'airplane'};
classes1(strcmp('2',classes1))={'automobile'};
classes1(strcmp('3',classes1))={'bird'};
classes1(strcmp('4',classes1))={'cat'};
classes1(strcmp('5',classes1))={'deer'};
classes1(strcmp('6',classes1))={'dog'};
classes1(strcmp('7',classes1))={'frog'};
classes1(strcmp('8',classes1))={'horse'};
classes1(strcmp('9',classes1))={'ship'};
classes1(strcmp('10',classes1))={'truck'};
But that was not successfull. It only replaced '10' with 'truck'.
UPDATE : This code will actually work. But in my case strings ' 1' has to be used instead '1' (a space was missing).
Use this to extend to your big case -
%%// Create look up and numeral data cell arrays for demo
LOOKUP_CELL_ARRAY = {'airplane','automobile','chopper'};
IN_CELL_ARRAY = num2cell(round(1+2.*rand(10,2)))
%%// Replace the second column of data cell array with corresponding
%%// strings in the look up array
IN_CELL_ARRAY(:,2)= LOOKUP_CELL_ARRAY(cell2mat(IN_CELL_ARRAY(:,2)))
Output -
IN_CELL_ARRAY =
[2] [2]
[2] [2]
[2] [1]
[2] [2]
[3] [1]
[2] [3]
[1] [1]
[3] [3]
[2] [2]
[2] [3]
IN_CELL_ARRAY =
[2] 'automobile'
[2] 'automobile'
[2] 'airplane'
[2] 'automobile'
[3] 'airplane'
[2] 'chopper'
[1] 'airplane'
[3] 'chopper'
[2] 'automobile'
[2] 'chopper'
You can do it as follows with cellfun:
% replacement strings
R = {'airplane','automobile','bird','cat','deer', ...
'dog','frog','horse','ship','truck'};
% example data
nums = randi(10,100,1);
data(:,1) = num2cell(nums)
data(:,2) = cellstr(num2str(nums))
data =
[ 3] ' 3'
[ 1] ' 1'
[ 1] ' 1'
[ 8] ' 8'
[ 8] ' 8'
[ 8] ' 8'
[ 7] ' 7'
[ 9] ' 9'
[ 1] ' 1'
...
str2double(x) does not care about whether its '01' or '1':
% replicate number strings with strings
data(:,2) = cellfun(#(x) R( str2double(x) ), data(:,2) )
data =
[ 3] 'bird'
[ 1] 'airplane'
[ 1] 'airplane'
[ 8] 'horse'
[ 8] 'horse'
[ 8] 'horse'
[ 7] 'frog'
[ 9] 'ship'
[ 1] 'airplane'
...
You can do it just with indexing:
data = {'aa' 1
'bb' 3
'cc' 2
'dd' 6
'ee' 1
'ff' 5}; %// example data: two-col cell array, 2nd col is numbers
str = {'airplane','automobile','bird','cat','deer', ...
'dog','frog','horse','ship','truck'}; %// replacement strings
data(:,2) = str(vertcat(data{:,2})); %// do the replacing

Replace strings with integer IDs in a Cell - Matlab

I have a cell that has string IDs. I need to replace them with integer IDs so that the cell can be transformed into a matrix. I especially need this to be a vectorized operation as the celldata is huge.
celldata = { 'AAPL' [0.1] ; 'GOOG' [0.643] ; 'IBM' [0.435] ; 'MMM' [0.34] ; 'AAPL' [0.12] ; 'GOOG' [1.5] ; 'IBM' [0.75] ; 'AAPL' [0.56] ; 'GOOG' [0.68] ; 'IBM' [0.97] ; };
I designed a sequential intID:
intIDs = {'AAPL' [1] ; 'GOOG' [2] ; 'IBM' [3] ; 'MMM' [4]};
intIDs contain ALL IDs that are possible in celldata. Also, celldata has IDs in sequential order and grouper together by dates. The date column is not shown here.
Desired result:
celldata = {[1] [0.1] ; [2] [0.643] ; [3] [0.435] ; [4] [0.34] ; [1] [0.12] ; [2] [1.5] ; [3] [0.75] ; [1] [0.56] ; [2] [0.68] ; [3] [0.97] ;};
Thanks!
You can use the ismember function and logical indexing to achieve what you want.
[~,indx]=ismember(celldata(:,1),intIDs(:,1));
celldata(:,1)=intIDs(indx,2)
celldata =
[1] [0.1000]
[2] [0.6430]
[3] [0.4350]
[4] [0.3400]
[1] [0.1200]
[2] [1.5000]
[3] [0.7500]
[1] [0.5600]
[2] [0.6800]
[3] [0.9700]