MATLAB: lecture de données à partir d’un fichier ASCII

Salut,
J’ai un fichier ASCII avec des données correspondant à plusieurs exécutions d’une simulation. Je veux tracer toutes les exécutions dans le même tracé à des fins de comparaison et je sais que je dois importer les données sous forme de matrice pour commencer tout autre traitement. Cependant, j’ai eu des problèmes avec l’importation des données. J’ai joint le fichier ici à titre de référence.
C’était mon point de vue sur la résolution de ce problème:
1. Utilisation de TextScan
 
fidi = fopen('data.txt');
D=textscan(fidi, '%u %u');
E = cell2mat(D);
 
Cependant, cela a renvoyé des cellules vides comme le montre la commande suivante:
 
whos E
Name Size Bytes Class Attributes
E 0x2 0 uint32
 
2. Utilisation de textread
 
fid = 'data.txt';
B = textread(fid, '%f %f');
 
Cela a renvoyé les erreurs suivantes:
 
Error using dataread
Number of outputs must match the number of unskipped input fields.
Error in textread (line 171)
[varargout{1:nlhs}]=dataread('file',varargin{:}); %#ok<REMFF1>

 
Ensuite, j’ai changé le code en ceci:
 
[B,C]=textread(fid, '%f %f');
 
Qui à son tour a renvoyé les erreurs suivantes:
 
Error using dataread
Trouble reading floating point number from file (row 1, field 1) ==> vds Id(M1)\n
Error in textread (line 171)
[varargout{1:nlhs}]=dataread('file',varargin{:}); %#ok<REMFF1>
 
3. Utilisation de spcread
 
B=spcread(fid);
 
Cela a donné l’erreur suivante:
 
Undefined function or variable 'spcread'.
 
4. Utilisation d’importdata
J’ai eu un succès limité avec ça, mais c’était aussi loin que je pouvais aller…
 
A=importdata(fid);
 
Cela m’a donné un fichier struct 1 × 1 avec un double 101 × 2 comprenant les 101 premières lignes du fichier texte et une cellule 2 × 1 avec les deux premières lignes d’en-tête.
J’ai ensuite supprimé tous les fichiers d’en-tête qui importaient l’intégralité des données, bien que sans tous les en-têtes et nécessiteraient la division en plusieurs matrices pour pouvoir tracer toutes les exécutions dans un graphique (car si je me souviens bien, la fonction de tracé ne prend pas en charge indexation des points pour les variables de la forme A.data) ainsi (sortie tirée d’un simulateur d’épices commercial):
Quelqu’un pourrait-il m’aider à importer correctement les données afin de pouvoir passer au tracé des courbes?

Meilleure réponse

  • L’importation de toutes les données du fichier sous forme de caractère, la conversion en chaîne, le fractionnement de cette chaîne en plusieurs petites chaînes, puis la conversion finale de ces nombreuses petites chaînes en numérique est compliquée, une utilisation inefficace de la mémoire (car sur chacune de ces conversions, vous dupliquez les données dans MATLAB) et implique plusieurs conversions de types de données (également inefficaces).
    La façon la plus efficace d’importer les données est d’obtenir la routine d’importation pour convertir directement les données en numérique, par exemple très simplement en utilisantTextScan(aucune duplication de données requise):
     
    opt = {'CollectOutput',true};
    hdr = {};
    out = {};
    [fid,msg] = fopen('data.txt','rt');
    assert(fid>=3,msg) % ensure the file opened correctly.
    fgetl(fid); % read and ignore the very first line.
    while ~feof(fid)
    hdr{end+1} = fgetl(fid);
    out(end+1) = textscan(fid,'%f%f',opt{:});
    end
    fclose(fid);
     
    Donner les onze groupes de données:
     
    >> size(out)
    ans =
    1 11
     
    Jetez un coup d’œil aux données importées:
     
    >> out{1}
    ans =
    0 0
    0.1 1.3168e-10
    0.2 1.3725e-10
    0.3 1.4305e-10
    0.4 1.4907e-10
    0.5 1.5532e-10
    0.6 1.6183e-10
    ... lots more lines here
    9.6 5.8922e-09
    9.7 6.1318e-09
    9.8 6.3811e-09
    9.9 6.6406e-09
    10 6.9106e-09
    >> out{11}
    ans =
    0 0
    0.1 0.00020176
    0.2 0.00038716
    0.3 0.00055754
    0.4 0.00071407
    0.5 0.00085781
    0.6 0.00098973
    0.7 0.0011107
    0.8 0.0012214
    0.9 0.0013227
    1 0.0014152
    1.1 0.0014994
    ... lots more lines here
    9.2 0.0027014
    9.3 0.0027099
    9.4 0.0027185
    9.5 0.002727
    9.6 0.0027355
    9.7 0.002744
    9.8 0.0027525
    9.9 0.0027611
    10 0.0027696
     
    La conversion des données d’en-tête intermédiaires en numérique est plus délicate car certains d’entre eux incluent des préfixes SI (par exemple, «  500m  » pour 0,5) mais une approche simpleTéléchargerma soumission FEXsip2numet faites quelque chose comme ça:
     

    >> mat = cell2mat(cellfun(@sip2num,strrep(hdr(:),'Inf',''),'uni',0))
    mat =
    0 1 11
    0.5 2 11
    1 3 11
    1.5 4 11
    2 5 11
    2.5 6 11
    3 7 11
    3.5 8 11
    4 9 11
    4.5 10 11
    5 11 11