MATLAB string cell array without loop - matlab

I am using a loop to create my cell array. It contains the string 'A1' to 'A10'.
Is there a way to iterate without using a loop ?
a = cell( 10, 1 );
for i = 1 : length( a )
a{i} = [ 'A', num2str( i ) ];
end
a =
'A1'
'A2'
'A3'
'A4'
'A5'
'A6'
'A7'
'A8'
'A9'
'A10'

I assume you want to build a without a loop. Let N = 10 as per your example.
Approach 1
a = sprintf('A%i ', 1:N);
a = a(1:end-1);
a = strsplit(a).';
This builds a char vector with a space after each number, removes the final space, splits on spaces, and transposes.
Approach 2
Another approach:
a = deblank(cellstr(strcat('A', strjust(num2str((1:10).'), 'left'))));
This concatenates 'A' with the numbers to form a 2D char array with some spaces; moves the spaces in each row to the right; converts each row into a cell; and removes trailing spaces on each cell.

If you have R2017a or later consider using string arrays instead of cell array of char vectors. You can create your string array using
"A"+(1:10)'

Related

How to get all possible combinations of array elements without duplicate

I have a vector of string elements vector = {'A','B','C'}.
I want to generate all possible combination of the three elements of the array but without duplicate.
I expect the following result: {'A', 'B', 'C', 'AB', 'AC', 'BC', 'ABC'}.
How can I do that in MATLAB?
Judging from your desired result, you want all the combinations with 2 choices of 'A', 'B', 'C', and '' (nothing). You can do it with nchoosek as follows
result = nchoosek(' ABC', 2) % note space for empty
Output
result =
6×2 char array
' A'
' B'
' C'
'AB'
'AC'
'BC'
Then removing the spaces and converting the combinations to a cell array:
result = strrep(cellstr(result), ' ', '')
As Wolfie pointed out, this only works for single character input, for multi character inputs we can use string arrays instead of char arrays:
result = nchoosek(["","A1","B2","C3"], 2);
result = result(:,1) + result(:,2) % string cat
% result = cellstr(result); % optional if want cell output
result =
6×1 string array
"A1"
"B2"
"C3"
"A1B2"
"A1C3"
"B2C3"

Split a Cell Array

I have a 150X1 cell array. Within the array there are multiple data types. The first cell contains 0.9VA = 1.012207; the second: 0.9VA_CLK = 0.020752; and so on like this (for the most part). I would like to split the cell into two cells using the = as the delimiter. Thus, {1,1}: 0.9VA and {1,2}: 1.012207; {2,1}: 0.9VA_CLK and {2,2}: 0.020752; so on and so forth. I have tried converting them to strings and then using strsplit; however, I run into problems because the string arrays are variable in size.
If there is any other information that I can provide please let me know. Thank you for your help and time in advance.
You can indeed apply strsplit to each of the strings (char arrays) in the cell array. To do so, you can use cellfun:
c{1} = '0.9VA = 1.012207';
c{2} = '0.9VA_CLK = 0.020752';
c{3} = 'CSIPhgenSWoffList = [0, 0, 0, 0]';
c{4} = 'SomethingElse = [0.020752, 0.24564]';
c = cellfun(#(x)strsplit(x,'='),c,'UniformOutput',false);
c = cat(1,c{:});
I use a small example cell array c here, containing four strings, I hope this is representative. I apply strplit to each cell in c using cellfun(x,'='), which splits at the equal sign and returns a cell array with cell arrays. That is, each string in c is turned into a cell array with 2 strings (e.g. '0.9VA ' and ' 1.012207'. This does leave some spaces at the beginning and end of the strings.
The next line, cat, converts this cell array of cell arrays into a two-dimensional cell array. The final output is a cell array c containing the same number of rows as the original cell array, and with 2 columns. The first column corresponds to the part before the equal sign, the second column to the part after the equal sign.
To remove the spaces, you can use cellfun again, with strtrim:
c = cellfun(#strtrim,c,'UniformOutput',false);

MatLab find column number of text cell array

I have a cell data type matrix containing a header and a large number of rows.
sample data:
set press dp
32.7045 17.805965 123.75047
32.690094 17.80584 123.74992
32.6232 17.815094 123.790115
I am trying to find the index of a specific column using the strcmp command to search through the all the data.
dpCol = strcmp([data{:}], 'dp')
This always returns
dpCol =
0
Am I using the data cell type wrong or something? Thank you!
Try using cell notation to yield just the 1st row, EG:
data(1,:) = {'set','press','dp'}
instead of unpacking* the entire cell array since strcmp can operate on cell arrays.
>>> data = {'set' 'press' 'dp'
32.7045 17.805965 123.75047
32.690094 17.80584 123.74992
32.6232 17.815094 123.790115}
data =
'set' 'press' 'dp'
[32.7045] [17.8060] [123.7505]
[32.6901] [17.8058] [123.7499]
[32.6232] [17.8151] [123.7901]
>>> col_idx = strcmp(data(1,:),'dp')
col_idx=
0 0 1
Then return the dp using the logical indices and cell2mat...
>>> dp = cell2mat(data(2:end,col_idx))
dp =
123.7505
123.7499
123.7901
or unpack* and concatenate the comma separated list
>>> dp = [data{2:end,col_idx}]
dp =
123.7505 123.7499 123.7901
As an alternative try cell2struct.
>>> datastruct = cell2struct(data(2:end,:),data(1,:),2)
datastruct =
3x1 struct array with fields:
set
press
dp
Then dp is ...
>>> dp = [datastruct.dp]
dp =
123.7505 123.7499 123.7901
* Using the colon operator inside curly braces unpacks an cell array into a comma separated list. Using square brackets horizontally concatenates the comma separated list which returns a character array set pressdp{{{ since the first item in the list is a character array. The garbage characters between and after 'set', 'press' and 'dp' are caused by reading the doubles as char. IE: char(32.7045) is the ASCII equivalent of whitespace. The arrays always get unpacked as column.

Creating an array from an str concatenation Matlab

Hello I have these two vectors
Q = [1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4]
and
Year = [2000,2000,2000,2000,2001,2001,2001,2001,2002.....]
and I would like to concatenate them into one single array Time
Time = [20001,20002,20003,20004,20010....]
Or
Time= {'2000Q1', '2000Q2', '2000Q3', '2000Q4', '2001Q1'....}
So far I tried with this code
m = zeros(136,1)
for i=1:136
m(i,1)= strcat(Q(i),Year(i));
end
And Matlab outputed me this:
Subscripted assignment dimension mismatch.
Help pls ?
If your vectors Year and Q have the same number of elements, you do not need a loop, just transpose them (or just make sure they are in column), then concatenate with the [] operator:
Time = [ num2str(Year.') num2str(Q.') ] ;
will give you:
20001
20002
20003
20004
20011
...
And if you want the 'Q' character, insert it in the expression:
Time = [ num2str(Year.') repmat('Q',length(Q),1) num2str(Q.') ]
Will give you:
2000Q1
2000Q2
2000Q3
2000Q4
2001Q1
...
This will be a char array, if you want a cell array, use cellstr on the same expression:
time = cellstr( [num2str(Year.') repmat('Q',length(Q),1) num2str(Q.')] ) ;
To obtain strings:
strtrim(mat2cell(num2str([Year(:) Q(:) ],'%i%i'), ones(1,numel(Q))));
Explanation:
Concat both numeric vectors as two columns (using [...])
Convert to char array, where each row is the concatenation of two numbers (using num2str with sprintf-like format specifiers). It is assumed that all numbers are integers (if not, change the format specifiers). This may introduce unwanted spaces if not all the concatenated numbers have the same number of digits.
Convert to a cell array, putting each row in a different cell (using mat2cell).
Remove whitespaces in each cell (using strtrim)
To obtain numbers: apply str2double to the above:
str2double(strtrim(mat2cell(num2str([Year(:) Q(:) ],'%i%i'), ones(1,numel(Q)))));
Or compute directly
10.^ceil(max(log10(Q)))*Year + Q;
You can use arrayfun
If you want your output in string format (with a 'Q' in the middle) then use sprintf to format the string
Time = arrayfun( #(y,q) sprintf('%dQ%d', y, q ), Year, Q, 'uni', 0 );
Resulting with a cellarray
Time =
'2000Q1' '2000Q2' '2000Q3' '2000Q4' '2001Q1' '2001Q2' '2001Q3'...
Alternatively, if you skip the 'Q' you can save each number in an array
Time = arrayfun( #(y,q) y*10+q, Year, Q )
Resulting with a regular array
Time =
20001 20002 20003 20004 20011 20012 20013 ...
Thats because you are initializing m to zeros(136,1) and then trying to save a full string into the first value. and obviously a double cannot hold a string.
I give you 2 options, but I favor the first one.
1.- you can just use cell arrays, so your code converts into:
m = cell(136,1)
for ii=1:136
m{ii}= strcat(Q(ii),Year(ii));
end
and then m will be: m{1}='2000Q1';
2.- Or if you know that your strings will ALWAYS be the same size (in your case it lokos like they are always 6) you can:
m = zeros(136,strsize)
for ii=1:136
m(ii,:)= strcat(Q(ii),Year(ii));
end
and then m will be: m(1,:)= [ 50 48 48 48 81 49 ] wich translated do ASCII will be 2000Q1

Updating N-gram 2 dimension cell array in Matlab

I am trying to extract bi-grams from a set of words and store them in a matrix. what I want is to insert the word in the first raw and all the bi-grams related to that word
for example: if I have the following string 'database file there' my output should be:
database file there
da fi th
at il he
ta le er
ab re
..
I have tried this but it gives me only the bigram without the original word
collection = fileread('e:\m.txt');
collection = regexprep(collection,'<.*?>','');
collection = lower(collection);
collection = regexprep(collection,'\W',' ');
collection = strtrim(regexprep(collection,'\s*',' '));
temp = regexprep(collection,' ',''',''');
eval(['words = {''',temp,'''};']);
word = char(words(1));
word2 = regexp(word, sprintf('\\w{1,%d}', 1), 'match');
bi = cellfun(#(x,y) [x '' y], word2(1:end-1)', word2(2:end)','un',0);
this is only for the first word however, i want to do that for every word in the "words" matrix 1X1000
is there an efficient way to accomplish this as I will deal with around 1 million words?
I am new to Matlab and if there any resource to explain how to deal with matrix (update elements, delete, ...) will be helpful
regards,
Ashraf
If you were looking to get a cell array as the output, this might work for you -
input_str = 'database file there' %// input
str1_split = regexp(input_str,'\s','Split'); %// split words into cells
NW = numel(str1_split); %// number of words
char_arr1 = char(str1_split'); %//' convert split cells into a char array
ind1 = bsxfun(#plus,[1:NW*2]',[0:size(char_arr1,2)-2]*NW); %//' get indices
%// to be used for indexing into char array
t1 = reshape(char_arr1(ind1),NW,2,[]);
t2 = reshape(permute(t1,[2 1 3]),2,[])'; %//' char array with rows for each pair
out = reshape(mat2cell(t2,ones(1,size(t2,1)),2),NW,[])'; %//'
out(reshape(any(t2==' ',2),NW,[])')={''}; %//' Use only paired-elements cells
out = [str1_split ; out] %// output
Code Output -
input_str =
database file there
out =
'database' 'file' 'there'
'da' 'fi' 'th'
'at' 'il' 'he'
'ta' 'le' 'er'
'ab' '' 're'
'ba' '' ''
'as' '' ''
'se' '' ''