Springen naar inhoud

Matlab complexe cell array naar csv file


  • Log in om te kunnen reageren

#1

Wouter_Masselink

    Wouter_Masselink


  • >5k berichten
  • 8246 berichten
  • VIP

Geplaatst op 07 september 2011 - 07:53

Ik heb een cell array (A) die meerdere cell arrays bevat

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.
"Meep meep meep." Beaker

Dit forum kan gratis blijven vanwege banners als deze. Door te registeren zal de onderstaande banner overigens verdwijnen.

#2

Drieske

    Drieske


  • >5k berichten
  • 10217 berichten
  • Moderator

Geplaatst op 07 september 2011 - 08:15

Misschien kan dit als inspiratie dienen?
Zoek je graag naar het meest interessante wetenschapsnieuws? Wij zoeken nog een vrijwilliger voor ons nieuwspostteam.

#3

Wouter_Masselink

    Wouter_Masselink


  • >5k berichten
  • 8246 berichten
  • VIP

Geplaatst op 08 september 2011 - 02:36

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.
"Meep meep meep." Beaker

#4

DePurpereWolf

    DePurpereWolf


  • >5k berichten
  • 9240 berichten
  • VIP

Geplaatst op 08 september 2011 - 07:55

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?

#5

Wouter_Masselink

    Wouter_Masselink


  • >5k berichten
  • 8246 berichten
  • VIP

Geplaatst op 08 september 2011 - 08:51

Elke cell kan verschillende dingen bevatten (int32, double etc).

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

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.

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:
??? 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)
"Meep meep meep." Beaker

#6

DePurpereWolf

    DePurpereWolf


  • >5k berichten
  • 9240 berichten
  • VIP

Geplaatst op 08 september 2011 - 09:10

zou je A op kunnen slaan naar een .mat bestand (dat bedoelde ik eigenlijk)

met save([filename '.mat'], 'A');
en dan hier plaatsen.

#7

Bart

    Bart


  • >5k berichten
  • 7224 berichten
  • VIP

Geplaatst op 08 september 2011 - 18:36

Ik heb een cell array (A) die meerdere cell arrays bevat

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).
If I have seen further it is by standing on the shoulders of giants.-- Isaac Newton

#8

DePurpereWolf

    DePurpereWolf


  • >5k berichten
  • 9240 berichten
  • VIP

Geplaatst op 08 september 2011 - 21:08

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.

#9

Wouter_Masselink

    Wouter_Masselink


  • >5k berichten
  • 8246 berichten
  • VIP

Geplaatst op 09 september 2011 - 01:30

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)
"Meep meep meep." Beaker

#10

DePurpereWolf

    DePurpereWolf


  • >5k berichten
  • 9240 berichten
  • VIP

Geplaatst op 09 september 2011 - 11:32

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.

% 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

#11

Wouter_Masselink

    Wouter_Masselink


  • >5k berichten
  • 8246 berichten
  • VIP

Geplaatst op 12 september 2011 - 02:30

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

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
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
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
for epr=1:size(B,2)
	for eps=2:size(B,1)
		B{1,epr} = vertcat(B{1,epr}, B{eps,epr});
	end
end
"Meep meep meep." Beaker





0 gebruiker(s) lezen dit onderwerp

0 leden, 0 bezoekers, 0 anonieme gebruikers

Ook adverteren op onze website? Lees hier meer!

Gesponsorde vacatures

Vacatures