Importazione dati da csv generici e differenti

di il
6 risposte

Importazione dati da csv generici e differenti

Buongiorno a tutti, e complimenti per il forum, sempre molto esaustivo.

vi espongo il mio problema:
ho bisogno di scrivere un codice che mi permetta di importare dati da due file csv, differenti, formati entrambi dalla prima riga con i "titoli" dei valori presenti in ogni colonna, e dalla seconda in poi con i valori sopradetti.
io vorrei poter importare i dati da questi .csv , come vettori colonna, con il nome descritto appunto dal "titolo", e il corpo appunto dai valori corrispondenti, per poter poi mettere a confronto i dati di vettori con lo stesso nome, per poterli analizzare e graficare.
il problema potrebbe essere che i due file non hanno i vettori nominati allo stesso modo(es. "time" nel file 1 e "tempo" nel file 2)
potete aiutarmi?

io pensavo di scrivere un codice in cui chiamavo due volte la funzione import per i due differenti file, ma cosi facendo non posso specificare gli output per poter poi lavorare con i vettori.

spero di essermi spiegato bene.

grazie mille

6 Risposte

  • Re: Importazione dati da csv generici e differenti

    Creare delle strutture dati (ad esempio vettori) il nome delle quali sia generato automaticamente, ancorchè possibile, è assolutamente sconsigliato.

    Se la struttura dei file è la stessa, se cioè le diverse colonne contengono lo stesso tipo di dato (ad esempio il tempo, pur se nella prima riga sono indicate con nomi diversi - tempo - time) pupi lavorare direttamente con le colonne della matrice che contiene tutti i dati, ti basta "ricordare" il numero della colonna che contiene i dati che ti interessano.

    Se la sequenza dei dati nelle colonne differisce da un file all'altro, allora, innanzitutto, sarebbe il caso di riverdere la procedura che crea i files di testo.

    Ad ogni moe, puoi usare la funzione importdata (https://it.mathworks.com/help/matlab/ref/importdata.html) per leggere i files di input.

    La funzione una struct nella quale trovi riga (header) con i nomi delle colonne ed un altro con i dati.

    Nel caso sia necessario puoi "lavorare" sul campo della struttura che contiene i nomi delle colonne e, eventualmente, risalire al numero della colonna che ti interessa.

    Se proprio vuoi delle variabili che abbiano il nome delle colonne, puoi provare, partendo dalla struttura creata dalla funzione importdata a generare una struttura i nomi dei campi della quale siano generati automaticamente in base al nome della colonna ed il relativo contenuto sia estratto ancora dalla struttura

    Partendo dall'esempio in https://it.mathworks.com/help/matlab/ref/importdata.html#btldf1f-1
    filename = 'myfile01.txt';
    delimiterIn = ' ';
    headerlinesIn = 1;
    A = importdata(filename,delimiterIn,headerlinesIn);
    
    % Identificazione del numero di colonne
    n_col=length(A.colheaders)
    % Creazione della nuova struttura
    % Loop sulle colonne
    for i=1:n_col
       % Il nome dei campio della struttura vengono generati automaticamente in
       % base al nome della colonna
       in_data.(A.colheaders{i})=A.data(:,i)
    end
    
  • Re: Importazione dati da csv generici e differenti

    Ciao ask, grazie mille della risposta, come sempre molto esaustiva.

    purtroppo i dati che devo analizzare io, sono generati da differenti "macchine", e soprattutto da differenti utenti, quindi sono obbligato a utilizzare il nome dei vettori generato automaticamente, se no non sarei in grado nemmeno di cominciare ad analizzarli.

    a tal proposito, come mai è sconsigliato farlo?

    comunque provo a mettere in atto i tuoi consigli, nelle varie forme per vedere il migliore.

    Grazie dell'aiuto
  • Re: Importazione dati da csv generici e differenti

    Le ragioni per la quali la creazione dinamica dei nomi delle vriabili (generalmente possibile con la funzione eval) è sconsigliata sono riportate qui https://it.mathworks.com/help/matlab/matlab_prog/string-evaluation.html

    Se potessi pubblicare un paio di esempi di files con nomi di colonne differenti e un esempio del tipo di utilizzo dei dati, forse sarebbe possibile fornire una soluzione efficace.
  • Re: Importazione dati da csv generici e differenti

    Ciao ask,
    qst un esempio di file csv che acqusisico:

    "Time","Distance","Gear","Engine RPM","Clutch RPM","Eng Oil Temp","Engine Temp","Engine Overheating","Fuel Level","G Force Lat","G Force Long",
    "0.000","0","5","5445","5445","85.09","66.92","0","15.000","0.04","-0.23"

    te ne posto solo una riga per semplicità se dovessi avere bisogno del file te lo mando.

    immagina che qst file vada importato e i canali( rappresentati dalle colonne) vadano confrontati con un altro file simile, in cui la tipologia di dati è la stessa ma viene esportato con i nomi delle colonne in italiano e disposte in ordine differente.

    a me serve ovviamente di confrontare le colonne con la stessa tipologia di dati, per fare un compare, è quindi necessario il nome del vettore per poterlo identificare non sapendo la sua collocazione.

    spero di essermi spiegato a sufficenza

    grazie ancora dell'aiuto
  • Re: Importazione dati da csv generici e differenti

    Scusami ti ho postato la riga con i nomi dei vettori e la prima riga di valori
  • Re: Importazione dati da csv generici e differenti

    I passi da seguire potrebbero essere:
    - lettura dei files di input
    - identificazione dei possibili nomi assunti da ognuna delle variabili (ad esempio TIme, Tempo)
    - selezione di una o più variabili
    - Identificazione del giusto accoppiamento dei nomi delle variabili
    - estrazione dei dati corrispondenti

    lettura dei files di input
    Dall'esempio di file che hai pubblicato, si deduce che in realtà non si tratta di veri CSV in quanto anche i valori numerici sono racchiusi tra ("), questo fa sì che il file non si possa leggere con, ad esempio csvread.
    I file si possono leggere con importdata che, in questo caso restituisce un cellarray di stringhe.
    Da questo cellarray si possono estrarre
    - i nomi delle variabili (dalla prima riga)
    - i dati numerici (dalle rimanenti righe). Per fare questo bisogna innanzitutto eliminare (con strrep le "virgolette", quindi convertire le stringhe innumeri con str2num. I dati numerici vengono così automaticamente convertiti in una matrice

    dentificazione dei possibili nomi assunti da ognuna delle variabili
    Questo passo non può essere automatizzato.
    Si può costruire un cellarray si stringhe che contenga, nelle varia colonne, tutti i possibili nomi delle variabili.
    Per fare un esempio, nel caso i nomi fossero i mesi dell'anno, si potrebbe creare un cellarray di questo tipo:
    var_table={'January','February','March','April','May','June','July'
       'Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno','Luglio'
       'Gen','Feb','Mar','Apr','Mag','Giu','Lug'};
    
    nel quale la prima colonna contiene i possibili "nomi" del primo mese dell'anno e così via.

    selezione di una o più variabili
    Si può definire un cellarray (un database) che contenga i nomi delle variabili che si intende estrarre dai files di input.
    Ad esempio (sempre continuando con i mesi dell'anno):
    sel_var={'Marzo','July','Gen'};
    La selezione può essere fatta indipendentemente dalla "lingua" e dall'ordine.

    Identificazione del giusto accoppiamento dei nomi delle variabili
    E' sufficiente cercare in quale colonna del cellarray / database è presente la variabile selezionata (conoscere la riga non serve)
    La colonna così individuata conterrà tutti i possibili nomi della variabile selezionata (ad es. March, Marzo, Mar).

    estrazione dei dati corrispondenti
    A questo punto avendo a disposizione per ognuno dei file:
    - l'elenco delle sue variabili
    - la matrice con i valori numerici
    ed avendo la colonna di associazione, ricercare il nome con il quale la variabile presente nel file, la sua posizione (numero della colonna) e procedere all'estrazione dei dati dalla matrice creata nei passi precedenti.

    Una possibile implementazione del processo appena descritto potrebbe essere la seguente:
    
    % Define the Variable names table
    var_table={'January','February','March','April','May','June','July'
       'Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno','Luglio'
       'Gen','Feb','Mar','Apr','Mag','Giu','Lug'};
    % Initialize the data struct, file counter and previous file name strung
    struct_data=struct;
    cnt=0;
    prev_file='';
    % Select and load two files
    while(cnt < 2)
       [FileName,PathName]=uigetfile('*.txt');
       if(FileName ~= 0)
          sel_file=fullfile(PathName,FileName);
          if(~strcmp(sel_file,prev_file))
             % Increment the counter
             cnt=cnt+1;
             row_data=importdata(sel_file);
             % Clean the first set of data
             % Remove the "
             clean_data=strrep(row_data,'"','');
             % Get the names of the columns form the first file
             vars=char(clean_data{1});
             % Split the names and remove the last one (since it is empty)
             vars=strsplit(char(clean_data{1}),',');
             vars(end)=[];
             % Get the numeric data
             data=str2num(char(clean_data(2:end)));
             % Create the data struct
             struct_data(cnt).vars=vars;
             struct_data(cnt).filename=sel_file;
             struct_data(cnt).data=data;
             % Store prev_file
             prev_file=sel_file;
          else
             choice=questdlg([prev_file ' already selected: Would you like to continue?'], ...
                'File Selection','Yes','No','Yes');
             if(strcmp(choice,'No'))
                disp('Same file selected twice: User selected not to continue');
                return;
             end
          end
       else
          choice=questdlg('File Selectioin Aborted: Would you like to continue?', ...
             'File Selection','Yes','No','Yes');
          if(strcmp(choice,'No'))
             disp('File selection Aborted: User selected not to continue');
             return;
          end
       end
    end
    
    % Select the variables
    sel_var={'Marzo','July','Gen'};
    % Get the number of variables
    n_sel_var=length(sel_var);
    % Locate the selected variable in the variable table
    for j=1:n_sel_var
       [r(j),c(j)]=find(strcmp(var_table,sel_var{j}));
       if(isempty(c(j)))
          disp(['ERROR: Selected variable ' sel_var ' not in the variable table'])
          return;
       end
    end
    
    % Get the variable alternate names
    alt_var=var_table(:,c);
    
    % Search the selected variable in the two input file
    % Initialize column array
    col=[];
    % Loop over the two input files data
    for i=1:2
       % Loop over the selected variables
       for j=1:n_sel_var
          % Loop over the alternative variable names
          for k=1:size(alt_var,1)
             % Search the possible name of teh var in the input data
             [r,c]=find(strcmp(struct_data(i).vars,alt_var{k,j}));
             % If found, store the number of the colunm and continue the loop
             if(~isempty(c))
                col(i,j)=c;
                break
             end
          end
       end
    end
    % If the varaible has not been foud then exit
    if(length(col) < 2)
       disp('ERROR: Variable not found in the input files')
       return
    end
    % Store the data for the selected variable and its alternative names in a
    % struct
    extracted_data(1).file=struct_data(1).filename
    extracted_data(2).file=struct_data(2).filename
    
    for i=1:2
       for j=1:size(col,2)
          extracted_data(i).(char(struct_data(i).vars(col(i,j))))=struct_data(i).data(:,col(i,j))
       end
    end
    % Get the data for the selected variable and its alternative names in the
    % two data set
    file_1=struct_data(1).filename
    file_2=struct_data(2).filename
    var_1={struct_data(1).vars{col(1,:)}}
    var_2={struct_data(2).vars{col(2,:)}}
    data_1=struct_data(1).data(:,col(1,:))
    data_2=struct_data(2).data(:,col(2,:))
    
    I seguuenti due esempi di file di input possono essere usati per testare il codice.

    t1.txt
    
    "January","February","March","April","May","June","July",
    "1.111","0","5","54.45","23.36","85.09","66.92",
    "2.222","0","5","54.45","54.3","85.09","93.13"
    
    t2.txt
    "Gennaio","Giugno","Febbraio","Aprile","Luglio","Maggio","Marzo",
    "56.153","165","11.541","78.9","12.3456","1.33","333.999",
    "41.56","0.541","546","7.74","431","-164","-48.54"
    
    Si può notare, nei due files, la differente "lingua" con la quale sono definite le variabili e le differenti posizioni relative.

    I dati di output sono memorizzati in due tipi di struttura dati
    - la struttura extracted_data con i nomi dei campi corrispondenti ai nomi delle variabili selezionate
    - una serie di matrici e celarray

    I commenti all'interno del codice dovrebbero fornire ulteriori spiegazioni ai passi sopra descritti.

    DISCLAIMER: nonostante abbia effettuato alcuni test, il codice deve essere testato ulteriormente con dei dati significativi per cui non è possibile garantirne la validità
Devi accedere o registrarti per scrivere nel forum
6 risposte