2010-01-11 4 views
6

J'ai écrit un script qui enregistre sa sortie dans un fichier CSV pour référence ultérieure, mais le deuxième script d'importation de données prend beaucoup de temps pour le relire.Le moyen le plus rapide d'importer des fichiers CSV dans MATLAB

les données sont dans le format suivant:

Item1,val1,val2,val3 
Item2,val4,val5,val6,val7 
Item3,val8,val9 

où les en-têtes sont sur la gauche la plus colonne et les valeurs de données prennent le reste de la ligne. Une difficulté majeure est que les tableaux de valeurs de données peuvent avoir des longueurs différentes pour chaque élément de test. Je l'enregistrerais en tant que structure, mais je dois pouvoir le modifier en dehors de l'environnement MATLAB, car parfois je dois supprimer des lignes de mauvaises données sur un ordinateur sur lequel MATLAB n'est pas installé. Donc vraiment, la première partie de ma question est: Dois-je enregistrer les données dans un format différent?

Deuxième partie de la question: J'ai essayé importdata, csvread et dlmread, mais je ne suis pas sûr qui est le mieux, ou s'il y a une meilleure solution. En ce moment j'utilise mon propre script en utilisant une boucle et fgetl, ce qui est horriblement lent pour les gros fichiers. Aucune suggestion?

function [data,headers]=csvreader(filename); %V1_1 
fid=fopen(filename,'r'); 
data={}; 
headers={}; 
count=1; 
while 1 
     textline=fgetl(fid); 
     if ~ischar(textline), break, end 
     nextchar=textline(1); 
     idx=1; 
     while nextchar~=',' 
     headers{count}(idx)=textline(1); 
     idx=idx+1; 
     textline(1)=[]; 
     nextchar=textline(1); 
     end 
     textline(1)=[]; 
     data{count}=str2num(textline); 
     count=count+1; 
end 
fclose(fid); 

(Je sais que ce code est probablement écrit terriblement - Je suis ingénieur, pas un programmeur, s'il vous plaît ne criez pas à moi -. Suggestions d'amélioration sont les bienvenues, cependant)

Répondre

10

il serait probablement rendre les données plus faciles à lire si vous pouviez pad le fichier avec NaN valeurs lors de votre premier script crée:

Item1,1,2,3,NaN 
Item2,4,5,6,7 
Item3,8,9,NaN,NaN 

ou vous pouvez même imprimer simplement les champs vides:

Item1,1,2,3, 
Item2,4,5,6,7 
Item3,8,9,, 

Bien sûr, pour bien capitonner, vous devez savoir quel est le nombre maximum de valeurs dans tous les éléments avant la main.

>> fid = fopen('uneven_data.txt','rt'); 
>> C = textscan(fid,'%s %f %f %f %f','Delimiter',',','CollectOutput',1); 
>> fclose(fid); 
>> C{1} 

ans = 

    'Item1' 
    'Item2' 
    'Item3' 

>> C{2} 

ans = 

    1  2  3 NaN %# TEXTSCAN sets empty fields to NaN anyway 
    4  5  6  7 
    8  9 NaN NaN 
3

Au lieu d'analyser la chaîne TextLine un caractère à la fois: avec par exemple format ci-dessus, vous pouvez ensuite utiliser l'une des fonctions de lecture de fichiers standard, comme TEXTSCAN. Vous pouvez utiliser strtok pour briser la chaîne jusqu'à par exemple

stringParts = {}; 
tline = fgetl(fid); 
if ~ischar(tline), break, end 
i=1; 
while 1 
    [stringParts{i},r]=strtok(tline,','); 
    tline=r; 
    i=i+1; 
    if isempty(r), break; end 
end 

% store the header 
headers{count} = stringParts{1}; 

% convert the data into numbers 
for j=2:length(stringParts) 
    data{count}(j-1) = str2double(stringParts{j}); 
end 
count=count+1; 
+0

+1 pour recommander strtok - Je ne savais pas qu'il existait avant – Doresoom

0

Q1) Si vous connaissez le nombre maximum de colonnes, vous pouvez remplir les entrées vides avec NaN En outre, si toutes les valeurs sont numériques, avez-vous vraiment besoin "Item #" colonne? Si oui, vous pouvez utiliser seulement "#", donc toutes les données sont numériques.

Q2) Le moyen le plus rapide de lire le num. les données d'un fichier sans mex-files sont csvread. J'essaie d'éviter d'utiliser des chaînes dans des fichiers csv, mais si je dois, j'utiliser ma fonction csv2cell:

http://www.mathworks.com/matlabcentral/fileexchange/20135-csv2cell

+0

La colonne Item # est en fait une étiquette de texte, donc oui, j'en ai vraiment besoin. J'aurais probablement dû clarifier cela. – Doresoom

1

J'ai eu le même problème avec les données csv de lecture dans Matlab, et je fus surpris par quel peu de soutien il y a pour cela, mais ensuite je viens de trouver l'outil de données d'importation. Je suis en r2015b.

Dans la barre supérieure de l'onglet "Accueil", cliquez sur "Importer des données" et choisissez le fichier que vous souhaitez lire.Une fenêtre d'application viendra comme ceci:

Import Data tool screenshot

Sous « Importer sélection » vous avez la possibilité de « générer la fonction », ce qui vous donne un peu d'options de personnalisation, y compris la façon de remplir les cellules vides, et ce que vous voulez que la structure de données de sortie soit. De plus, il est écrit par MathWorks, donc il utilise probablement la méthode la plus rapide disponible pour lire les fichiers csv. C'était presque instantané sur mon dossier.

Questions connexes