2016-10-04 3 views
0

Ich habe eine CSV-Datei mit ein paar Mustern. Ich möchte nur selektiv Zeilen in die CSV-Reader-Klasse von Python laden. Derzeit nimmt CSV nur ein Dateiobjekt. Gibt es eine Möglichkeit, dies zu umgehen?
Mit anderen Worten, was ich brauche, ist:Selektiv füttern Python CSV-Klasse mit Linien

with open('filename') as f: 
    for line in f: 
     if condition(line): 
      record = csv.reader(line) 

Aber zur Zeit, csv-Klasse schlägt fehl, wenn es eine Linie statt eines Dateiobjekt gegeben ist.

Antwort

3

Vom csv.reader docstring:

csvfile kann jedes Objekt sein, die das Iterator-Protokoll unterstützt und gibt einen String zurück jedes Mal seine __next__() Methode aufgerufen wird

können Sie füttern csv.reader mit einem Generator-Iterator, der nur die ausgewählten Zeilen liefert.

with open('filename') as f: 
    lines = (line for line in f if condition(line)) 
    for record in csv.reader(lines): 
     do_something() 
+0

weiterzuleiten. Es gibt ein anderes Problem. Die "Zeilen" können bis zu 16 GB groß sein. In diesem Fall werden wir die Daten nicht nach csv streamen, sondern würden effektiv warten, bis die Zeilen gefüllt sind, und dann den csv-Leser aufrufen, was schlecht ist. – sreeraag

+0

@sreeraag Nein, es ist ein [Generatorausdruck] (https://docs.python.org/3/glossary.html#term-generator-ausdruck "Generatorausdruck"), es wird nicht ausgefüllt, sondern generiert Werte nach Bedarf. – Goyo

+0

Einverstanden, aber aus irgendeinem Grund, nach dieser Änderung, wächst das Gedächtnis meines Prozesses ständig weiter. – sreeraag

1
import shlex 
lex = shlex.shlex('"sreeraag","100,ABC,XYZ",112',',', posix=True) 
lex.whitespace += ',' 
lex.whitespace_split = True 
print list(lex) 

ergibt

['sreeraag', '100,ABC,XYZ', '112'] 
+0

Der Vorteil csv Leser Klasse ist, dass es Fälle wie diese Griffe: "sreeraag", "100, ABC, XYZ", 112 Splitting durch '' im obigen Fall versagen . – sreeraag

+0

ist das besser? –

+0

Das funktioniert nicht für viele csv-Anwendungsfälle – sreeraag

1

Um Datei als Stream lesen Sie diese nutzen können.

io.open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True) 
+0

Sogar offen (Dateiname) gibt mir einen Stream. Das Problem besteht darin, den Stream nach einigen vorbereitenden Überprüfungen an die Klasse csvreader – sreeraag

0

eine Lösung gefunden: Als csv Objekt, das __next unterstützt erwartet __(), ich bin mit einer StringIO Klasse String StringIO Objekt, das wiederum zu konvertieren __next Griffen __() und gibt für csv einer Zeile jedes Mal Leserklasse.

with open('filename') as f: 
for line in f: 
    if condition(line): 
     record = csv.reader(StringIO.StringIO(line)) 
+0

Auf diese Weise erstellen Sie ein StringIO und ein Lesegerät für jede Zeile. Außerdem wird es viel Arbeit für den Müllsammler geben. Es wird eine Leistungseinbuße geben, es sei denn, diese Vorgänge sind im Vergleich zur Bewertung der Bedingung vernachlässigbar. – Goyo

0

`` `

with open("xx.csv") as f: 
    csv = f.readlines() 
    print(csv[0]) 

` ``

→ _ → Das Leben ist kurz, Ihre Notwendigkeit Pandas

pip installieren Pandas

`` `

import pandas as pd 
df = pd.read_csv(filepath or url) 
df.ix[0] 
df.ix[1] 
df.ix[1:3] 

`` `

+1

Pandas mag keine unregelmäßigen CSVs –