If I create a cell array using:
clear all
data = {rand(1,5),rand(1,4),rand(1,4),rand(1,6)};
a = cell(1,length(data));
how is it then possible to create a cell array in each cell of a which is the same length as the corresponding cell in data. I know this can easily be done using a loop, but how would it be possible by using the cellfun function?
Do you want something like that?
data = {rand(1,5),rand(1,4),rand(1,4),rand(1,6)};
a2=cellfun(#(x) cell(size(x)),data,'UniformOutput',0)
a2 =
{1x5 cell} {1x4 cell} {1x4 cell} {1x6 cell}
You could also accomplish this by using CELLFUN to just get the sizes of each cell, create all the cells you need, then divide them up using MAT2CELL:
>> cellSizes = cellfun('size',data,2);
>> a = mat2cell(cell(1,sum(cellSizes)),1,cellSizes)
a =
{1x5 cell} {1x4 cell} {1x4 cell} {1x6 cell}
Related
I have a data structure that has a cell array "mydata", which has 250 rows of cells that look like this:
{1x1 cell}
{1x2 cell}
{1x4 cell}
{1x1 cell}
.
.
.
I want to have separate files which are only 1x1, but at the same time. I don't wanna change the length of my cell array and instead want to find a way to pass any extra component to new files and if there is nothing extra, it becomes an empty cell.For example, if one cell is 1x2 with cells like "rose" and "blue", in one file I wanna have "rose" and in the other file, "blue" to be saved.
I get "matrix index is out of range for deletion" for the following script. What is the issue in it? Is there any more straightfoward way to do what I want?
Part of what I've done:
mydata= structure.mydata;
first_file = cell(numel(mydata),1);
second_file = cell(numel(mydata),1);
for i = 1 : length(structure.mydata)
content = structure.mydata(i);
first_file(i) = content(1);
if length(content) > 1
second_file(i) = content(2);
else
second_file(i) = [];
end
end
I'm trying to make some logic work with some legacy matlab code. I figured the easist thing was to make the data look the same as what the code is expecting.
I'm reading the relevant data from a CSV file, it's pretty simple -- but the format for the IDs changed from a simple number to an ID of the form [YY,ZZZZ].
As an example, the 'previous' CSV data looked like:
1,Simple,Data
2,More,Data-Dash-Data
3,Even,More
4,Really,More
The 'new' CSV data looks like:
[01,0001],Simple,Data
[02,1001],More,Data-Dash-Data
[03,9876],Even,More
[04,1234],Really,More
Previously, to read in the data, this logic was used:
fid = fopen(fileName);
data = textscan(fid,'%s%s%s%*s','Delimiter',',');
When this was done against the 'previous' CSV data, it returned data that look like this:
data =
1×3 cell array
{4×1 cell} {4×1 cell} {4×1 cell}
The cells then look like:
K>> data{:}
ans =
4×1 cell array
'1'
'2'
'3'
'4'
ans =
4×1 cell array
'Simple'
'More'
'Even'
'Data'
ans =
4×1 cell array
'Data'
'Data-Dash-Data'
'More'
'Data'
So to handle the ID of the form [YY,ZZZZ], I had to modify the 'textscan' logic to handle the new ID format that we're using. To do that, I'm using a regexp function:
fid = fopen(fileName);
rawData = textscan(fid,'%s','Delimiter','\n');
data = regexp(rawData{1},'[ \-\/\w]*([\[][^\)\]]*[\]])?', 'match')
This then, after it reads in the data, gives me data that is formatted like this:
K>> data
data =
4×1 cell array
{1×3 cell}
{1×3 cell}
{1×3 cell}
{1×3 cell}
K>> data{:}
ans =
1×3 cell array
'[01,0001]' 'Simple' 'Data'
ans =
1×3 cell array
'[02,1001]' 'More' 'Data-Dash-Data'
ans =
1×3 cell array
'[03,9876]' 'Even' 'More'
ans =
1×3 cell array
'[04,1234]' 'Really' 'More'
So you can see that it has the correct data in it -- but the data is laid out differently which is breaking on the legacy code. So my question is how can I make the 'new' data be laid out like this as it was coming out of the 'textscan' logic:
data =
1×3 cell array
{4×1 cell} {4×1 cell} {4×1 cell}
You can use fileread to read in the raw file directly. Afterwards, you can use a regex which splits on either a comma, not followed by a digit, or on a carriage return.
c = regexp(fileread(fileName),',(?!\d)|\r\n','split');
formattedData = {c(1:3:end)',c(2:3:end)',c(3:3:end)'};
>> formattedData
formattedData =
1×3 cell array
{4×1 cell} {4×1 cell} {4×1 cell}
In MATLAB (R2015b) I have a cell C (1x4 cell, with 4 columns):
C = [4x1 double] [4x1 double] {4x1 cell} {4x1 cell}
And when I call C I get the printout above, but I want MATLAB to write it as:
[10] [31.2] 'TRS' 'BLU'
[12] [34.2] 'TRS' 'BLU'
[13] [33.5] 'TRS' 'BLU'
[14] [34.8] 'TRS' 'BLU'
I.e. a 4x4 cell. How can I get this printout? Thanks
You need to convert the first two elements to cell arrays and then you can horizontally contatenate them and display them
[num2cell(c{1}), num2cell(c{2}), c{3:end}]
I think this can work
for i=1:numel(c)
fprintf('%g %g %s %s\n',c{1}(i),c{2}(i),c{3}{i},c{4}{i})
end
Do not get confused with row numbers in the arrays. I am just asking converting 1 into style 2
This is Cell Array C
I want to convert it to the below version how can i do that ?
V2 =
If I understand correctly, you have a flat cell array of strings (which contain valid MATLAB cell array definitions), and you want to convert each string into a sub-cell-array of its own. So what you need is:
cellfun(#eval, C, 'UniformOutput', false)
Where C is the original cell array of strings.
Example:
C = {'{''samsung'', ''n150'', ''jp0xtr'', ''n570''};'; ...
'{''samsung'', ''n150'', ''jp0xtr'', ''beyaz''};'}
C2 = cellfun(#eval, C, 'UniformOutput', false)
The result is:
C =
'{'samsung', 'n150', 'jp0xtr', 'n570'};'
'{'samsung', 'n150', 'jp0xtr', 'beyaz'};'
C2 =
{1x4 cell}
{1x4 cell}
I would like to sort a cell array according to one of the columns. The array is created by textscan function. There are some answers on web, but I still cannot get it working. I have the following array:
>> DATA
DATA =
{303427x1 cell} {303427x1 cell} {303427x1 cell} {303427x1 cell} [303427x1 uint32] [303427x1 double] [303427x1 uint32] [303427x1 int32] {303427x1 cell}
Important is the sixth column, which are times converted by datenum function. I want to sort the whole DATA by this column but with the link to another columns.
Normal sort or sortrows doesnt work for me. Could you help me please?
I take it you want to sort within each cell of DATA, correct? The datenum function produces serial time stamps since "year zero," so they can be sorted normally.
times = DATA{6};
[~,idx] = sort(times,'ascend');
for i=1:length(DATA)
DATA{i} = DATA{i}(idx);
end
You can avoid for-loop in #reve_etrange's answer by using CELLFUN after you get the sorting index idx.
DATA = cellfun(#(x) x(idx), DATA, 'UniformOutput', false);