reshape a cell array to be row major

2 visualizzazioni (ultimi 30 giorni)
Al Danial
Al Danial il 30 Mag 2022
Risposto: Al Danial il 30 Mag 2022
If I load data with textscan() I'll get back a cell array holding the columns of data. For example
fh = fopen('log.txt');
x = textscan(fh, '%s %f');
fclose(fh);
and a file log.txt containing
xyz 1.73
uvw 3.66
srt 4.73
klm 1.14
then x will be populated as
>> x
1×2 cell array
{4×1 cell} {4×1 double}
and x{2}, for example, returns the four values in column 2.
What I want instead is for x{2} to give me the contents of the 2nd row, not the 2nd column. At the moment I'm using a double loop to create a new cell array, y, containing the data row-major:
n_rows = length(x{1});
n_cols = length(x);
y = cell(n_rows,1);
for r = 1:n_rows
for c = 1:n_cols
y{r}{c} = x{c}(r);
end
end
Is there a cleaner (shorter, more elegant) solution?

Risposta accettata

Voss
Voss il 30 Mag 2022
Maybe storing the data in a table will end up being more convenient:
t = readtable('log.txt')
t = 4×2 table
Var1 Var2 _______ ____ {'xyz'} 1.73 {'uvw'} 3.66 {'srt'} 4.73 {'klm'} 1.14
t(2,:)
ans = 1×2 table
Var1 Var2 _______ ____ {'uvw'} 3.66
However, to get a cell array like you ask for:
fh = fopen('log.txt');
x = textscan(fh, '%s');
fclose(fh);
x = reshape(x{1},2,[]).';
x(:,2) = cellfun(@str2double,x(:,2),'Uniform',false);
x = num2cell(x,2);
x{2}
ans = 1×2 cell array
{'uvw'} {[3.6600]}
x{2}{1}
ans = 'uvw'
Note that this x is not quite the same as your y:
fh = fopen('log.txt');
x = textscan(fh, '%s %f');
fclose(fh);
n_rows = length(x{1});
n_cols = length(x);
y = cell(n_rows,1);
for r = 1:n_rows
for c = 1:n_cols
y{r}{c} = x{c}(r);
end
end
y{2}
ans = 1×2 cell array
{1×1 cell} {[3.6600]}
y{2}{1}
ans = 1×1 cell array
{'uvw'}
y{2}{1}{1}
ans = 'uvw'

Più risposte (1)

Al Danial
Al Danial il 30 Mag 2022
Your first sentence, "Maybe storing the data in a table will end up being more convenient:" proved to be the key. With that idea I was able to get the simple solution I was after:
y = rows2vars(readtable('log.txt'));
y = y{:,2:end}'; % omit variable names
The y here will need to be indexed as y{r,c} instead of y{r}{c} but that's merely syntax. Thanks for the tip.

Categorie

Scopri di più su Dates and Time in Help Center e File Exchange

Prodotti


Release

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by