I have a cell array (n-by-1 dimension) containing both strings and cells, which looks something like this
{
{'r1'} % -> cell content is in format 'char'
{'r2'} % -> cell content is in format 'char'
{1x2 cell} % -> cell content is a cell array: [{'r1'}{'r2'}]
{'r3'} % -> cell content is in format 'char'
{1x2 cell} % -> cell content is a cell array: [{'r1'}{'r3'}]
{1x2 cell} % -> cell content is a cell array: [{'r2'}{'r3'}]
{1x3 cell} % -> cell content is a cell array: [{'r1'}{'r2'}{'r3'}]
...
}
I need to find the row-index where the some string is included, e.g. 'r2'. I usually use strfind for this purpose which works great if the cell array has a consistent format (hence 'char'-format within each cell).
Is there any way to apply this function to the cell array structure which is displayed above?
Thanks!
EDIT: Please find attached three images showing the data structure that I am using, since I am not sure how to exactly show/explain the hierarchies and layers of the cell array in text. Hope that helps. Also find attached the outcome of the code.
Code used:
change = 'r1.m';
srch = cellfun(#(x) strfind(x, change), strats, 'UniformOutput', false);
stringInRow = cellfun(#(x) numel(x) == 1 || (numel(x)>1)*numel(cell2mat(x))>0, srch);
rows = find(stringInRow);
You could use two subsequent cellfun calls: one to perform the string search (cell by cell), and one to evaluate it (found string true or not false?)
%// example data
c{1} = 'r1';
c{2} = 'r2';
c{3}{1} = 'r1'; c{3}{2} = 'r2';
c{4} = 'r3';
c{5}{1} = 'r1'; c{5}{2} = 'r3';
%// example search
searchForString = 'r2';
srch = cellfun(#(x) strfind(x, searchForString), c, 'UniformOutput', false);
stringInRow = ...
cellfun(#(x) numel(x) == 1 || (numel(x)>1)*numel(cell2mat(x))>0, srch);
%// ^-. short-circuit scalars here ^
%// |
%// since cell2mat is valid only for cells or empty arrays
With resulting stringInRow:
stringInRow =
0 1 1 0 0
If you want to explicitly list the rows, you can just make use of find on the stringInRow boolean vector
>> foundStringInRows = find(stringInRow)
foundStringInRows =
2 3
Related
I have many 33213168x1 cell arrays, where each cell contains an 85 x 1 column.
Each cell in the column is in the form
[0.55;0.25;0.75]
[0.33;0.66;0.99]
I want to split up this single column by the semi-colon delimiter so that each cell in the cell array is 85x3, like:
[0.55][0.25][0.75]
[0.33][0.66][0.99]
I've tried numerous techniques to solve this, but most commonly get the errors 'cell elements must be character arrays' or 'input must be a string.'
Some of the approaches I've tried:
splitcells = strsplit(regress_original_053108,';');
splitcells = cellfun(#(x) strsplit(regress_original_053108, ';'),regress_original_053108 , 'UniformOutput',0);
splitcells = regexp(regress_original_053108, ';', 'split');
splitcells = textscan(regress_original_053108, 'delimiter', ';');
Etc. Any feedback about how to do this would be appreciated.
Hope this solves your problem:
% Example input
input = {[0.55;0.25;0.75]};
cellArray(1:85,1) = input;
% Create array
doubleArray = zeros(85,3);
% Fill array
for i=1:85
doubleArray(i,:) = cellArray{i,1}';
end
Each cell you have is not a string, hence you can't use strsplit. Use this approach:
for ii = length(X) % Here X denotes your 33213168x1 cell array
X{ii} = cell2mat(cellfun(#(y) y.', X{ii}, 'UniformOutput', false));
end
I have matrix A = 50x2
How to convert the data into cell array.
Should be I have 10 cell which each cell contain data [5x2].
Thank you for help.
That is what mat2cell does:
A = rand(50,2); % example matrix
N = 10; % number of cells in which to split the first dimension
result = mat2cell(A, repmat(size(A,1)/N, 1, N), size(A,2));
One can use num2cell:
N_ROWS = 5; N_COLS = 2;
A = rand(50,2);
B = num2cell(reshape(A,N_ROWS,N_COLS,[]),[1,2]); % B is 1x1x10 cell array
What this does is turn your input array into 5x2 "slices" stacked along the 3rd dimension.
You can add a squeeze(B), B = B(:) or a reshape(B,[],1) at the end if you need the output as a column vector.
So my main objective is to take a matrix of form
matrix = [a, 1; b, 2; c, 3]
and a list of identifiers in matrix[:,1]
list = [a; c]
and generate a new matrix
new_matrix = [a, 1;c, 3]
My problem is I need to import the data that would be used in 'matrix' from a tab-delimited text file. To get this data into Matlab I use the code:
matrix_open = fopen(fn_matrix, 'r');
matrix = textscan(matrix_open, '%c %d', 'Delimiter', '\t');
which outputs a cell array of two 3x1 arrays. I want to get this into one 3x2 matrix where the first column is a character, and the second column an integer (these data formats will be different in my implementation).
So far I've tried the code:
matrix_1 = cell2mat(matrix(1,1));
matrix_2 = cell2mat(matrix(1,2));
matrix = horzcat(matrix_1, matrix_2)
but this is returning a 3x2 matrix where the second column is empty.
If I just use
cell2mat(matrix)
it says it can't do it because of the different data formats.
Thanks!
This is the help of matlab for the cell2mat function:
cell2mat Convert the contents of a cell array into a single matrix.
M = cell2mat(C) converts a multidimensional cell array with contents of
the same data type into a single matrix. The contents of C must be able
to concatenate into a hyperrectangle. Moreover, for each pair of
neighboring cells, the dimensions of the cell's contents must match,
excluding the dimension in which the cells are neighbors. This constraint
must hold true for neighboring cells along all of the cell array's
dimensions.
From what I understand the contents you want to put in a matrix should be of the same type otherwise why do you want a matrix? you could simply create a new cell array.
It's not possible to have a normal matrix with characters and numbers. That's why cell2mat won't work here. But you can store different datatypes in a cell-array. Use cellstr for the strings/characters and num2cell for the integers to convert the contents of matrix. If you have other datatypes, use an appropriate function for this step. Then assign them to the columns of an empty cell-array.
Here is the code:
fn_matrix = 'data.txt';
matrix_open = fopen(fn_matrix, 'r');
matrix = textscan(matrix_open, '%c %d', 'Delimiter', '\t');
X = cell(size(matrix{1},1),2);
X(:,1) = cellstr(matrix{1});
X(:,2) = num2cell(matrix{2});
The result:
X =
'a' [1]
'b' [2]
'c' [3]
Now we can do the second part of the question. Extracting the entries where the letter matches with one of the list. Therefore you can use ismember and logical indexing like this:
list = ['a'; 'c'];
sel = ismember(X(:,1),list);
Y(:,1) = X(sel,1);
Y(:,2) = X(sel,2);
The result here:
Y =
'a' [1]
'c' [3]
I want to find cells, which are at the same position in two different cell arrays and which have specific values.
The two cell arrays have the following structure:
cell array C1= cell(20,1). In each cell there is another cell cell(8129,8) holding double values in the range of [0,1].
Cell array C2= cell(20,1). In each cell there is another cell cell(8192,8) also holding double values in the range of [0,1].
I know want to find those cells, which (1) have a specific value that I determine (e.g. C1_value = 0.8 and C2_value = 0.85) and (2) are at the same position in the respective sub cell (!) array (e.g. C1{2}(736) == 0.8 and C2(19)(736) == 0.85). NOTE: The same position only refers to the subcell arrays (cell(8192,8)) not the "main" cell arrays C1(:) and C2(:)
Thanks in advance!
See if this approach works for you -
sz = cell2mat(cellfun(#size,C1(1),'uni',0))
row1 = sz(1);
col1 = sz(2);
t1 = reshape(horzcat(C1{:}),row1,col1,[])
t2 = reshape(horzcat(C2{:}),row1,col1,[])
b1 = t1==C1_value
b2 = t2==C2_value
tt1 = reshape(b1,row1*col1,[])' %//'
tt2 = reshape(b2,row1*col1,[])' %//'
tt22 = permute(tt2,[3 2 1])
tt3 = bsxfun(#and,tt1,tt22)
[C1_cellnum,subcellnum,C2_cellnum] = ind2sub(size(tt3),find(tt3)) %// outputs
Thus, with your sample data, you must have -
C1_cellnum as 2, C2_cellnum as 19 and subcellnum as 736.
Suppose I have a vector created after concatenating horizontally 3 variables:
>>a=1;
>>b=0;
>>c=1;
>>vector=horzcat(a,b,c);
Now what i want to do is converting this vector to string and put this vector in a cell table.
>>string=mat2str(vector);
>>string =
[1 0 1]
>> C = cell(2, 2);
>> C{1}{1}=string
>> C =
{1x1 cell} []
[] []
My problem is: how to search for this value in a cell array? i tried the following:
find(strcmp(C, string))
ans =
Empty matrix: 0-by-1
as you can see, matlab can't find this vector converted to string inside the cell array. Is there any easier way to do this?
Are you sure you want this:
C{1}{1}=string
and not this:
C{1,1}=string
?
If you use the second method, then find(strcmp... will work. The first method won't work because you are making a cell matrix within a cell matrix and then asking strcmp to compare your string directly with a cell...