Lire tout un fichier texte dans une variable MATLAB à la fois
Je voudrais lire un (gros) fichier journal dans un MATLAB chaîne de cellules en une seule étape. J'ai pris l'habitude:
s={};
fid = fopen('test.txt');
tline = fgetl(fid);
while ischar(tline)
s=[s;tline];
tline = fgetl(fid);
end
mais c'est juste lent. J'ai trouvé que
fid = fopen('test.txt');
x=fread(fid,'*char');
est plus rapide, mais j'obtiens un nx1
char matrice, x
. J'ai pu essayer et de les convertir x
à une chaîne de cellules, mais puis-je obtenir dans l'encodage de l'enfer; séparateur de ligne semble être \n\r ou 10 et 56 dans ASCII (j'ai regardé la fin de la première ligne), mais ces deux personnages qui, souvent, ne suivez pas les uns des autres et même de se montrer en solo, parfois.
Est-il un simple moyen rapide pour lire un fichier ASCII dans une chaîne de cellules en une seule étape, ou de convertir x
à une chaîne de cellules?
Lecture via fgetl:
Code Calls Total Time % Time
tline = lower(fgetl(fid)); 903113 14.907 s 61.2%
Lecture via fread:
>> tic;for i=1:length(files), fid = open(files(i).name);x=fread(fid,'*char*1');fclose(fid); end; toc
Elapsed time is 0.208614 seconds.
J'ai testé preallocation, et elle n'aide pas 🙁
files=dir('.');
tic
for i=1:length(files),
if files(i).isdir || isempty(strfind(files(i).name,'.log')), continue; end
%# preassign s to some large cell array
sizS = 50000;
s=cell(sizS,1);
lineCt = 1;
fid = fopen(files(i).name);
tline = fgetl(fid);
while ischar(tline)
s{lineCt} = tline;
lineCt = lineCt + 1;
%# grow s if necessary
if lineCt > sizS
s = [s;cell(sizS,1)];
sizS = sizS + sizS;
end
tline = fgetl(fid);
end
%# remove empty entries in s
s(lineCt:end) = [];
end
toc
Temps écoulé est 12.741492 secondes.
Près de 10 fois plus rapide que l'original:
s = textscan(fid, '%s', 'Delimiter', '\n', 'whitespace', '', 'bufsize', files(i).bytes);
J'ai dû mettre 'whitespace'
à ''
afin de garder les espaces de tête (dont j'ai besoin pour l'analyse), et "bufsize' la taille du fichier (par défaut 4000 jeta un dépassement de la mémoire tampon d'erreur).
OriginalL'auteur stephan hattinger | 2010-08-21
Vous devez vous connecter pour publier un commentaire.
La raison principale de votre premier exemple est lent, c'est que
s
pousse à chaque itération. Cela signifie recréer un nouveau tableau, copie de l'ancien lignes, et l'ajout de la nouvelle, qui ajoute une surcharge inutile.Pour accélérer les choses, vous pouvez preassign
s
Voici un petit exemple de ce que preallocation peut faire pour vous
MODIFIER
Comme une alternative à
fgetl
, vous pouvez utiliser TEXTSCANCe lit les lignes de
test.txt
comme une chaîne de caractères dans la cellule de la matrice des
en une seule fois.Oui, c'est fait. Voir mon edit.
Très bien, merci. Juste pour être sûr, j'ai répliqué avec des chaînes de caractères avec des longueurs variables, et vous avez eu une énorme augmentation de la performance.
Je vous remercie pour votre réponse rapide! j'ai codé l'exemple pour montrer que le problème général, mais ne pense pas que le fait que, probablement, pas de pré-affectation dans l'exemple serait de ralentir les choses. cependant, dans mon cas, j'ai instantanément analyser les lignes, c'est à dire il n'y a pas de chaîne de cellules de la s. profilage conduit à environ 60% du temps passé dans la ligne "tline = fgetl(fid);" (avec l'autre code n'étant pas optimisés pour l'instant).
hattinger: Quel type d'analyse faites-vous? Pourriez-vous utiliser textscan, ou fscanf pour faire l'analyse?
OriginalL'auteur Jonas
J'ai tendance à utiliser urlread pour cela, par exemple:
La variable str contient alors un gros bloc de texte de type chaîne de caractères (prêt pour la regexp pour fonctionner sur).
OriginalL'auteur Paul Hughes
Utiliser le
fgetl
fonction au lieu defread
. Pour plus d'info, allez iciOriginalL'auteur Hari Menon
s = regexp(fileread('test.txt'), '(\r\n|\n|\r)', 'split");
Les coquillages exemple dans Matlab regexp la documentation est directement sur.
OriginalL'auteur Ben