Simple usecase. Έχουμε ένα αρχείο csv από το οποίο θέλουμε να διαβάσουμε μόνο ορισμένες στήλες.
Advanced usecase. Έχουμε να διαβάσουμε δεδομενα από κάποια αρχεία csv τα οποία έχουν μεν τις στήλες που χρειαζόμαστε, όμως οι στήλες αυτές δεν είναι με κοινή σειρά σε όλα τα αρχεία. Ένας τρόπος για να το λύσουμε αυτό είναι να διαβάζουμε τη header line, να βρίσκουμε σε ποιες στήλες είναι τα field που μας ενδιαφέρουν, και να διαβάζουμε μόνο αυτά.
Και τα δύο είναι εύκολο να γίνουν, γράφοντας έναν custom DictReader. Ουσιαστικά είναι απλοποιημένος ο default DictReader του module csv, Σε σχέση με τον default έχουν αλλάξει τα arguments. Αντί του fieldnames δίνεται το dictionary fields που είναι της μορφής
{column_index: field_name}
import csv
from operator import itemgetter
class DictReaderPicker(object):
def __init__(self, f, fields, dialect="excel", *args, **kwds):
super(DictReaderPicker, self).__init__()
self.reader = csv.reader(f, dialect, *args, **kwds)
self.dialect = dialect
self.fieldnames = fields.values()
self.columns = fields.keys()
self.column_picker = itemgetter(*self.columns)
def __iter__(self):
return self
def next(self):
row = self.reader.next()
# unlike the basic reader, we prefer not to return blanks,
# because we will typically wind up with a dict full of None
# values
while row == []:
row = self.reader.next()
# When there is specified only one column, the column picker returns
# a single object like a string or a number but the zip needs an iterable,
# so we create it manually.
if len(self.columns) == 1:
d = dict(zip(self.fieldnames, (self.column_picker(row),)))
else:
d = dict(zip(self.fieldnames, self.column_picker(row)))
return d
Π.χ. αν ονομάσουμε το ακόλουθο αρχείο "test.csv"
"Id";"Class";"Date"
1;"a";08/18/07
2;"b";08/19/07
3;"c";08/20/07
4;"d";08/21/07
5;"e";08/22/07
6;"f";08/23/07
7;"g";08/24/07
8;"h";08/25/07
9;"i";08/26/07
Και θέλουμε να διαβάσουμε μόνο την πρώτη και την τρίτη στήλη, μπορούμε να το κάνουμε ως εξής:
filename = "test.csv"
fields = {0: "Id", 2: "Dates"}
try:
inputfile = open(filename, "rb")
except IOError as e:
raise e
else:
reader = DictReaderPicker(inputfile,
dialect=csv.excel,
fields=fields,
delimiter=str(";"),
skipinitialspace=True)
# Skip header line
row = reader.next()
ids = []
dates = []
for row in reader:
print(row)
dates.append(row['Dates'])
ids.append(row['Id'])
print(dates)
Όπως βλέπουμε η κάθε row αποτελείται μόνο από τα fields που δηλώσαμε.