2012-12-21 7 views
44

I miei dati di origine sono in un file TSV, 6 colonne e più di 2 milioni di righe.lettura e analisi di un file TSV, quindi manipolazione per il salvataggio come CSV (* efficiently *)

Ecco quello che sto cercando di realizzare:

  1. ho bisogno di leggere i dati in 3 delle colonne (3, 4, 5) in questo file sorgente
  2. La quinta colonna è un numero intero . Ho bisogno di utilizzare questo valore intero per duplicare una voce di riga con l'utilizzo dei dati nella terza e quarta colonna (per il numero di volte integer).
  3. Voglio scrivere l'output di # 2 in un file di output in formato CSV.

Di seguito è quello che è venuto fuori.

La mia domanda: è un modo efficace per farlo? Sembra che potrebbe essere intenso se tentato su 2 milioni di righe.

Innanzitutto, ho creato un file di tab separato con cui lavorare e l'ho chiamato "sample.txt". E 'piuttosto semplice e ha solo quattro righe:

Row1_Column1 Row1-Column2 Row1-Column3 Row1-Column4 2 Row1-Column6 
Row2_Column1 Row2-Column2 Row2-Column3 Row2-Column4 3 Row2-Column6 
Row3_Column1 Row3-Column2 Row3-Column3 Row3-Column4 1 Row3-Column6 
Row4_Column1 Row4-Column2 Row4-Column3 Row4-Column4 2 Row4-Column6 

allora ho questo codice:

import csv 

with open('sample.txt','r') as tsv: 
    AoA = [line.strip().split('\t') for line in tsv] 

for a in AoA: 
    count = int(a[4]) 
    while count > 0: 
     with open('sample_new.csv','ab') as csvfile: 
      csvwriter = csv.writer(csvfile, delimiter=',') 
      csvwriter.writerow([a[2], a[3]]) 
     count = count - 1 

risposta

96

è necessario utilizzare il modulo di csv per leggere il file con valori separati da tabulazioni. Fare non leggerlo in memoria in un colpo solo. Ogni riga che hai letto ha tutte le informazioni necessarie per scrivere righe nel file CSV di output, dopotutto. Mantieni aperto il file di output.

import csv 

with open('sample.txt','rb') as tsvin, open('new.csv', 'wb') as csvout: 
    tsvin = csv.reader(tsvin, delimiter='\t') 
    csvout = csv.writer(csvout) 

    for row in tsvin: 
     count = int(row[4]) 
     if count > 0: 
      csvout.writerows([row[2:4] for _ in xrange(count)]) 

o, utilizzando il modulo itertools fare la ripetizione con itertools.repeat():

from itertools import repeat 
import csv 

with open('sample.txt','rb') as tsvin, open('new.csv', 'wb') as csvout: 
    tsvin = csv.reader(tsvin, delimiter='\t') 
    csvout = csv.writer(csvout) 

    for row in tsvin: 
     count = int(row[4]) 
     if count > 0: 
      csvout.writerows(repeat(row[2:4], count)) 
+2

Grazie, questo è perfetto. Avrei votato la risposta, ma non ho più abbastanza punti Rep. Questo è quello che ottengo facendo una domanda stupida che viene messa sottosopra. – CJH

+1

@ CJH: NP, ha già raggiunto il cap rep oggi, quindi per la mia reputazione non avrebbe fatto la differenza. :-) –

+1

Ci scusiamo per la mia ignoranza, ma cosa significa il trattino basso nell'ultima riga? –