2013-06-06 10 views
5

Ho un file ".CSV" che sto cercando di analizzare usando CSV in ruby. Il file ha due file di intestazioni e non l'ho mai incontrato prima e non so come gestirlo. Di seguito è riportato un esempio delle intestazioni e delle righe.Ruby: come posso leggere un file CSV che contiene due intestazioni in Ruby?

fila 2

"Institution ID","Institution","Game Date","Uniform Number","Last Name","First Name","Rushing","","","","","Passing","","","","","","Total Off.","","Receiving","","","Pass Int","","","Fumble Ret","","","Punting","","Punt Ret","","","KO Ret","","","Total TD","Off xpts","","","","Def xpts","","","","FG","","Saf","Points" 

fila 2

"","","","","","","Rushes","Gain","Loss","Net","TD","Att","Cmp","Int","Yards","TD","Conv","Plays","Yards","No.","Yards","TD","No.","Yards","TD","No.","Yards","TD","No.","Yards","No.","Yards","TD","No.","Yards","TD","","Kicks Att","Kicks Made","R/P Att","R/P Made","Kicks Att","Kicks Made","Int/Fum Att","Int/Fum Made","Att","Made"

fila 3

"721","AirForce","09/01/12","19","BASKA","DAVID","","","","","","","","","","","","0","0","","","","","","","","","","2","85","","","","","","","","","","","","","","","","","","","0"

Non ci sono ritorni nell'esempio sopra ho appena aggiunto loro quindi sarebbe più facile da leggere. Lo CSV ha metodi disponibili per gestire questa struttura o dovrò scrivere i miei metodi per gestirlo? Grazie!

+0

Nel tuo esempio, posso vedere solo una riga di intestazione, non due. Potresti per favore postare un esempio che mostri più linee? – Tilo

+0

'" ID istituto "' inizia la prima riga dell'intestazione. '" "," "," "," "," "," "," Rushes "' avvia la seconda riga di intestazione. Spero che ti aiuti a chiarirlo. – daveomcd

+0

la seconda riga di intestazione contiene 2 colonne in meno rispetto alla prima – Tilo

risposta

3

Dovrai scrivere la tua logica. CSV è in realtà solo righe e colonne, e di per sé non ha alcuna idea intrinseca di cosa sia realmente ogni colonna o riga, è solo dati grezzi. Pertanto, CSV non ha alcun concetto o consapevolezza di avere due righe di intestazione, è una cosa umana, quindi dovrai costruire la tua euristica.

Dato che le righe di dati assomigliano:

"721","Air Force","09/01/12", 

Quando si avvia l'analisi dei dati, se la prima colonna rappresenta un numero intero, allora, se si converte a un int e se è > 0 di quanto tu creda hai a che fare con una "riga" valida e non con un'intestazione.

+0

Grazie questa è molto utile. Avevo guardato attraverso la documentazione di Ruby CSV e non ho visto nulla, quindi sono contento di vedere che non diventerò cieco! – daveomcd

1

Read the CSV in e saltare la prima linea in uscita:

arr_of_arrs = CSV.read("path/to/file.csv") 
arr_of_arrs[2..arr_of_arrs.length].each do |x| 
    # operation here 
end 
+0

'[1:]' - quale sintassi è questa? –

+0

Come notato nel montaggio, ho confuso il mio pitone e il rubino. Vota la risposta, se ti fa sentire meglio. – hd1

+0

Non dovrebbe essere '[2.' invece di' [1.'? –

6

Sembra che il file CSV è stato prodotto da un foglio di calcolo di Excel che ha colonne raggruppate in questo modo:

... |  Rushing  |   Passing   | ... 
... |Rushes|Gain|Loss|Net|TD|Att|Cmp|Int|Yards|TD|Conv| ... 

(non è sicuro se Ho ripristinato correttamente i gruppi.)

Non esistono strumenti standard per lavorare con questo tipo di file CSV, AFAIK. Devi fare il lavoro manualmente.

  • Leggere la prima riga, trattarla come prima riga di intestazione.
  • Leggere la seconda riga, trattarla come seconda riga di intestazione.
  • Leggere la terza riga, trattarla come prima linea dati.
  • ...
+1

Solo curioso - perché downvote? :) –

4

Mi consiglia di utilizzare l'smarter_csv gioiello, e fornisco manualmente le intestazioni corrette:

require 'smarter_csv' 
options = {:user_provided_headers => ["Institution ID","Institution","Game Date","Uniform Number","Last Name","First Name", ... provide all headers here ... ], 
      :headers_in_file => false} 
data = SmarterCSV.process(filename, options) 
data.pop # to ignore the first header line 
data.pop # to ignore the second header line 
# data now contains an array of hashes with your data 

Si prega di consultare la pagina GitHub per le opzioni, e gli esempi. https://github.com/tilo/smarter_csv

Un'opzione da utilizzare è :user_provided_headers e quindi è sufficiente specificare le intestazioni desiderate in un array. In questo modo puoi risolvere casi come questo.

È necessario fare data.pop per ignorare le righe di intestazione nel file.

+0

Grazie, darò un'occhiata! – daveomcd

+0

puoi per favore caricare un piccolo file CSV di esempio da qualche parte? per esempio. come un succo? Dovrebbe essere facile aggiungere una funzione a 'smarter_csv' per quello. – Tilo

+0

Questo aiuto? http://codepad.org/37kUMMsF – daveomcd

1

È davvero facile farlo con CSV. Basta guardare per vedere che cosa il numero di riga corrente è che è stato letto, e ciclo fino a quando avete letto le intestazioni:

require 'csv' 

CSV.foreach('test.csv') do |row| 
    next unless $. > 2 
    puts "'" + row.join("', '") + "'" 
end 

Quando viene eseguito questo è ciò che viene emesso:

'721', 'Air Force', '09/01/12', '19', 'BASKA', 'DAVID', '', '', '', '', '', '', '', '', '', '', '', '0', '0', '', '', '', '', '', '', '', '', '', '2', '85', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '0' 

$. è la linea -numero dell'ultima riga letta dal file che è stato aperto. Quindi, questo immediatamente si interrompe fino a quando $. ha letto due righe.

+0

Puoi anche usare '$ INPUT_LINE_NUMBER' per ottenere il numero di riga corrente, che trovo essere un po 'più esplicito per te stesso e gli altri in fondo alla strada. –

Problemi correlati