1 van 1

Matlab complexe cell array naar csv file

Geplaatst: wo 07 sep 2011, 08:53
door Wouter_Masselink
Ik heb een cell array (A) die meerdere cell arrays bevat

Code: Selecteer alles

 A= 

  Columns 1 through 3

{ 3x1 cell  }	{ 3x1 cell}	{ 3x1 cell}

[22x1 double]	{22x1 cell}	{22x1 cell}

[22x1 double]	{22x1 cell}	{22x1 cell}

[22x1 double]	{22x1 cell}	{22x1 cell}

  Column 4

{ 3x1 cell }

[22x1 int32]

[22x1 int32]

[22x1 int32]
Het totaal aantal rijen in cell array A is variabel, de kolommen zijn altijd hetzelfde. Ik ben op zoek naar een manier om al deze arrays binnen cell array A onder te brengen in 1 enkele matrix om deze vervolgens te exporteren naar .csv met een komma delimiter.

Ik heb al zitten neuzen in cell2mat, maar dit werk alleen wanneer telkens hetzelfde data type gebruikt wordt. Dat is in mijn geval duidelijk niet het geval. Als iemand suggesties heeft voor een alternatief dan zou dat fantastisch zijn.

Re: Matlab complexe cell array naar csv file

Geplaatst: wo 07 sep 2011, 09:15
door Drieske
Misschien kan dit als inspiratie dienen?

Re: Matlab complexe cell array naar csv file

Geplaatst: do 08 sep 2011, 03:36
door Wouter_Masselink
Dat kan me in zoverre inspireren dat ik nu serieus aan het overwegen ben om alle dingen handmatig in de database uit te gaan voeren. Wat ik wil lijkt onmogelijk terwijl het handmatig een kwestie van knip en plak werk is, meer niet.

Er moet toch een manier zijn om de meerdere datafiles samen te voegen waarvan de headers identiek zijn en waarbij de headers van de eerste file bovenaan de nieuwe file komen te staan. Ik ga maar eens kijken naar andere manieren om die csv files te openen in matlab want nu ben ik met for loops aan het kloten, dat schiet ook niet op.

Re: Matlab complexe cell array naar csv file

Geplaatst: do 08 sep 2011, 08:55
door DePurpereWolf
Ik zie het probleem niet zo, zijn de lengte van de cells altijd gelijk?

Een paar regeltjes code zou dat toch allemaal in een matrix moeten zetten, en dan gaat copieren naar een csv file makkelijk.

Ik ben niet zo goed in coderen dus zal ik er op het werk even naar moeten kijken.

Kun je een matlab bestand toevoegen?

Re: Matlab complexe cell array naar csv file

Geplaatst: do 08 sep 2011, 09:51
door Wouter_Masselink
Elke cell kan verschillende dingen bevatten (int32, double etc).

De aantal kolommen zijn altijd gelijk, de aantal rijen kunnen verschillen.

Code: Selecteer alles

Track Length

 ==================== 

Value,Unit,Category,ID,

181.913,um,Track,1000000000,

224.144,um,Track,1000000001,

174.764,um,Track,1000000002,

167.377,um,Track,1000000003,

18.034,um,Track,1000000004,

129.058,um,Track,1000000005,

118.710,um,Track,1000000006,

120.174,um,Track,1000000007,

128.558,um,Track,1000000008,

119.663,um,Track,1000000009,

121.350,um,Track,1000000010,

64.082,um,Track,1000000011,

98.510,um,Track,1000000012,

54.149,um,Track,1000000013,

73.641,um,Track,1000000014,

57.139,um,Track,1000000015,

65.790,um,Track,1000000016,

50.941,um,Track,1000000017,

89.714,um,Track,1000000018,

19.365,um,Track,1000000019,

13.018,um,Track,1000000020,

14.924,um,Track,1000000021,
Hiermee wil ik het bestand opdelen in headers (de eerste drie rijen) en data (de rest)

Vervolgens neem ik nog een bestand met dezelfde opmaak (slechts andere getallen voor de kolom value).

Dit probeer ik met devolgende M-file te doen.

Code: Selecteer alles

function concatenate_track_files

h=gcf;

close(h)

[filename,pathname,index]=uigetfile('*.csv','select file containing track data','/Users/wmasseli/Desktop/microscopy data');

fid1=fopen(strcat(pathname,filename));

X = (filename);

% Read 3 header lines

HeadersX = textscan(fid1, repmat('%s', 1, 4), 3, 'Delimiter', ',');

% Read body

DataX = textscan (fid1, '%f%s%s%d', 'Delimiter', ',');

%Close file

fid1 = fclose(fid1);

A = cat (1,HeadersX,DataX)

  keepLooping = true;

  while keepLooping	   % Loop while keepLooping is true

  

   [filename,pathname,index]=uigetfile('*.csv','select track file to concatenate with previous file(s)','/Users/wmasseli/Desktop/microscopy data');

fid1=fopen(strcat(pathname,filename));

X = (filename);

% Read 3 header lines

HeadersX = textscan(fid1, repmat('%s', 1, 4), 3, 'Delimiter', ',');

% Read body

DataX = textscan (fid1, '%f%s%s%d', 'Delimiter', ',');

%Close file

fid1 = fclose(fid1);

A = cat (1,A,DataX);

h = gcf;

close (h);

% Create pushbutton figure

hFigure = figure('Position',[200 200 120 70],'Resize','off',...

'MenuBar','none');

% Create first pushbutton

uicontrol('Style', 'pushbutton', 'String', 'Stop','Position',...

[10 10 50 50],'callback',@stop_button);

% Creat second pushbutton

uicontrol('Style', 'pushbutton', 'String', 'Continue','Position',...

[70 10 50 50], 'callback',@continue_button);

pause (5);

  end

%---Begin nested functions---

   function stop_button(~,~)

keepLooping = false;

 % Set keepLooping to false

   end

function continue_button(~,~)

keepLooping = true;

 % Set keepLooping to true

end

h = gcf;

close (h);

% Write all arrays in A to a single array

B = cell2mat(A)

end
Hierbij krijg ik de volgende error:

Code: Selecteer alles

??? Error using ==> cell2mat at 46

All contents of the input cell array must be of the same data type.

Error in ==> concatenate_track_files at 61

cell2mat(A)

Re: Matlab complexe cell array naar csv file

Geplaatst: do 08 sep 2011, 10:10
door DePurpereWolf
zou je A op kunnen slaan naar een .mat bestand (dat bedoelde ik eigenlijk)

met save([filename '.mat'], 'A');

en dan hier plaatsen.

Re: Matlab complexe cell array naar csv file

Geplaatst: do 08 sep 2011, 19:36
door Bart
Wouter_Masselink schreef:Ik heb een cell array (A) die meerdere cell arrays bevat

Code: Selecteer alles

 A= 

  Columns 1 through 3

{ 3x1 cell  }	{ 3x1 cell}	{ 3x1 cell}

[22x1 double]	{22x1 cell}	{22x1 cell}

[22x1 double]	{22x1 cell}	{22x1 cell}

[22x1 double]	{22x1 cell}	{22x1 cell}

  Column 4

{ 3x1 cell }

[22x1 int32]

[22x1 int32]

[22x1 int32]
Het totaal aantal rijen in cell array A is variabel, de kolommen zijn altijd hetzelfde. Ik ben op zoek naar een manier om al deze arrays binnen cell array A onder te brengen in 1 enkele matrix om deze vervolgens te exporteren naar .csv met een komma delimiter.

Ik heb al zitten neuzen in cell2mat, maar dit werk alleen wanneer telkens hetzelfde data type gebruikt wordt. Dat is in mijn geval duidelijk niet het geval. Als iemand suggesties heeft voor een alternatief dan zou dat fantastisch zijn.
Zolang je niet weet wat er in de sub-cellen zit, kun je er niets mee. Elk element in de sub-cellen zou namelijk een matrix of weer een cell array kunnen bevatten.

Vraagje: is de data op deze manier aangeleverd of heb je deze zelf gegenereerd. In het laatste geval (maar eigenlijk ook in het eerste): begin met data management. Zet alle data die je ontvangt, genereert of inleest direct op in zinvolle formaten. Structures zijn hier erg handig bij. Vermijd cell arrays (behalve bij strings van verschillende lengtes).

Re: Matlab complexe cell array naar csv file

Geplaatst: do 08 sep 2011, 22:08
door DePurpereWolf
Ik heb een vergelijkend probleem gehad met textscan. Die pleurt dingen nu eenmaal in een cellarray.

Er is een optie in textscan die sommige dingen al concateneerd maar je moet dan nog steeds met horzcat en vertcat werken.

Helemaal niet moeilijk als je het weet, en ik denk dat WM daar mee zit. Soms zijn de simpelste dingen moeilijk te vinden.

Ik wacht tot morgen wanneer ik weer achter een pc met matlab ben. Ik kan nooit code schrijven uit de losse pols.

Re: Matlab complexe cell array naar csv file

Geplaatst: vr 09 sep 2011, 02:30
door Wouter_Masselink
De data is in csv files aangeleverd, ik heb er zelf dit wat je nu ziet van gemaakt. Het is belangrijk dat de data na processing ook weer in csv files (met dezelfde lay-out) komt te staan. zodoende zijn alle tests die ik heb ontwikkeld hier nog steeds op uit te voeren.

Op verzoek is de output van A gesaved in .mat. (download linkje)

Re: Matlab complexe cell array naar csv file

Geplaatst: vr 09 sep 2011, 12:32
door DePurpereWolf
Het was wel een gekloot zeg,

het volgende zou je een Cell array moeten geven dat je kunt printen.

Doordat er strings inzitten heb ik de nummers naar strings om moeten zetten. Daar kun je niet omheen.

Als je de optie 'CollectOutput' gebruikt in textscan kun je een paar stappen overslaan.

Code: Selecteer alles

% De optie ('CollectOutput', 1) maakt het colleren makkelijker.

% textscan(file_id, format, block_size, 'TreatAsEmpty', 'No Data', 'HeaderLines', 0, 'CollectOutput', 1);

clear 

Filename = 'testing.mat';

load(Filename, 'A');

B=A;

for epr=1:size(B,2)

for eps=2:size(B,1)

B{1,epr} = vertcat(B{1,epr}, B{eps,epr});

end

end

% Column 2 and 3 are now done, but column 1 and 4 need a bit more unnesting.

C(:,2)=B{1,2};

C(:,3)=B{1,3};

for eps=5:size(B{1,1},1)

B{1,1}{4,1} = vertcat(B{1,1}{4,1}, B{1,1}{eps,1});

end

C(1:3,1)=B{1,1}(1:3,1);

% need to convert numbers to string as can't convert cell to number.

for eps=1:size(B{1,1}{4,1},1)

C{3+eps,1}=num2str(B{1,1}{4,1}(eps,1));	 

end

for eps=5:size(B{1,4},1)

B{1,4}{4,1} = vertcat(B{1,4}{4,1}, B{1,4}{eps,1});

end

C(1:3,4)=B{1,4}(1:3,1);

for eps=1:size(B{1,4}{4,1},1)

C{3+eps,4}=num2str(B{1,4}{4,1}(eps,1)) ;

end

Re: Matlab complexe cell array naar csv file

Geplaatst: ma 12 sep 2011, 03:30
door Wouter_Masselink
Dit werkt!

Ik probeerde de cell array C vervolgens te saven als csv file, csvwrite heeft hier geen zin in. Echter er is een functie cell2csv (beschikbaar in de matlab fileexchange)link die de cell array C direct saved als csv file waarbij je zelf aan kan geven wat er als seperator gebruikt moet worden.

Nu zit ik nog met een vergelijkbare structuur die in plaats van een %f %s %s %d structuur een %f %s %s %d %d %d structuur heeft. Ik ga even met je code stoeien en eens kijken wat ik er van kan maken.

EDIT:

dat is me nu gelukt. Echter wanneer ik een file met de structuur %f %f %f %s %s %s %d %d %d probeer te verwerken dan krijg ik een error bij het verwerken van kolom 2

Code: Selecteer alles

A = 

  Columns 1 through 5

{   3x1 cell  }	{   3x1 cell  }	{   3x1 cell  }	{   3x1 cell}	{   3x1 cell}

[6259x1 double]	[6259x1 double]	[6259x1 double]	{6259x1 cell}	{6259x1 cell}

[6259x1 double]	[6259x1 double]	[6259x1 double]	{6259x1 cell}	{6259x1 cell}

[6259x1 double]	[6259x1 double]	[6259x1 double]	{6259x1 cell}	{6259x1 cell}

  Columns 6 through 9

{   3x1 cell}	{   3x1 cell }	{   3x1 cell }	{   3x1 cell }

{6259x1 cell}	[6259x1 int32]	[6259x1 int32]	[6259x1 int32]

{6259x1 cell}	[6259x1 int32]	[6259x1 int32]	[6259x1 int32]

{6259x1 cell}	[6259x1 int32]	[6259x1 int32]	[6259x1 int32]

??? Index exceeds matrix dimensions.

Error in ==> concatenate_XYZ_position_files at 92

for eps=1:size(B{1,2}{4,1},1)
met de bijbehorende code

Code: Selecteer alles

B=A;

for epr=1:size(B,4)

for eps=2:size(B,1)

B{1,epr} = vertcat(B{1,epr}, B{eps,epr});

end

end

% Column 4, 5 and 6 are now done, but column 1, 2, 3 and 7, 8, 9 need a bit more unnesting.

C(:,4)=B{1,4};

C(:,5)=B{1,5};

C(:,6)=B{1,6};

  for eps=5:size(B{1,1},1)

B{1,1}{4,1} = vertcat(B{1,1}{4,1}, B{1,1}{eps,1});

end

C(1:3,1)=B{1,1}(1:3,1);

for eps=1:size(B{1,1}{4,1},1)

C{3+eps,1}=num2str(B{1,1}{4,1}(eps,1));

end

for eps=5:size(B{1,2},1)

B{1,2}{4,1} = vertcat(B{1,2}{4,1}, B{1,2}{eps,1});

end

C(1:3,2)=B{1,2}(1:3,1);

   

for eps=1:size(B{1,2}{4,1},1)

C{3+eps,2}=num2str(B{1,2}{4,1}(eps,1));

end

for eps=5:size(B{1,3},1)

B{1,3}{4,1} = vertcat(B{1,3}{4,1}, B{1,3}{eps,1});

end

C(1:3,3)=B{1,3}(1:3,1);

   

for eps=1:size(B{1,3}{4,1},1)

C{3+eps,3}=num2str(B{1,3}{4,1}(eps,1));

end

for eps=5:size(B{1,7},1)

B{1,7}{4,1} = vertcat(B{1,7}{4,1}, B{1,7}{eps,1});

end

C(1:3,7)=B{1,7}(1:3,1);

for eps=1:size(B{1,7}{4,1},1)

C{3+eps,7}=num2str(B{1,7}{4,1}(eps,1));

end

for eps=5:size(B{1,8},1)

B{1,8}{4,1} = vertcat(B{1,8}{4,1}, B{1,8}{eps,1});

end

C(1:3,8)=B{1,8}(1:3,1);

for eps=1:size(B{1,8}{4,1},1)

C{3+eps,8}=num2str(B{1,8}{4,1}(eps,1));

end

for eps=5:size(B{1,9},1)

B{1,9}{4,1} = vertcat(B{1,9}{4,1}, B{1,9}{eps,1});

end

C(1:3,9)=B{1,9}(1:3,1);

for eps=1:size(B{1,9}{4,1},1)

C{3+eps,9}=num2str(B{1,9}{4,1}(eps,1));

end

cell2csv('concatenateXYZ.csv',C,',')
EDIT:

dit heb ik ook op weten te lossen. Er was een foutje in het eerste stuk code geslopen.

Er staat

Code: Selecteer alles

for epr=1:size(B,4)

for eps=2:size(B,1)

B{1,epr} = vertcat(B{1,epr}, B{eps,epr});

end

end
maar dat moest het volgende zijn

Code: Selecteer alles

for epr=1:size(B,2)

for eps=2:size(B,1)

B{1,epr} = vertcat(B{1,epr}, B{eps,epr});

end

end