CSV failide töötlemine Pythonis22. Oct '14
CSV failist ajatemplite ja näitude lugemine ning nende järgi tekstifaili, HTML ja Excel 2007 faili genereerimine:
# -*- coding: utf-8 -*-
FAILINIMI = "SCADAsync_5min.csv"
import numpy
from codecs import open # Impordib Python3 stiilis open()
from datetime import datetime
from pytz import timezone # Python 2.x
print "Loen:", FAILINIMI
m = []
now = datetime.now()
kpv_esimene = None
with open(FAILINIMI, encoding="utf-8") as fh:
# Söö päis ära
fh.readline()
for line in fh:
# Lõõ sõne laiali ; järgi
tulbad = line.strip().split(";")
# Parsi naiivne kellaaeg (ei tea ajatsooni)
kpv_cet = datetime.strptime(tulbad[0], "%Y-%m-%d %H:%M:%S+00:00")
# Pane ajatsooni info CET külge ja siis teisenda UTC-ks
kpv_utc = kpv_cet.\
replace(tzinfo=timezone("CET")).\
astimezone(timezone("UTC"))
if not kpv_esimene:
kpv_esimene = kpv_utc
# Tagantpoolt neljandast kuni lõpuni
n2idud = tulbad[-4:]
try:
n1, n2, n3, n4 = [float(i) for i in n2idud]
except ValueError:
continue
m.append(n1)
# Tee list numpy massiiviks
m = numpy.array(m)
# Arvuta keskmine numpy abil
average = numpy.mean(m)
raporti_read = (
u"Esimese näidu aeg: %s" % kpv_esimene,
u"Viimase näidu aeg: %s" % kpv_utc,
u"Näide oli: %d" % len(m),
u"Keskmine näit: %.02f MW" % average
)
# Standardväljund
for rida in raporti_read:
print rida
# HTML raport
with open("raport.html", "w", encoding="utf-8") as fh:
fh.write("<html>")
fh.write("<head>")
fh.write("<meta charset='utf-8'>")
fh.write("</head>")
fh.write("<body>")
fh.write("<h1>%s</h1>" % datetime.now())
for rida in raporti_read:
fh.write("<p>" + rida + "</p>")
fh.write("</body>")
fh.write("</html>")
# Tekstiraport
with open("raport.txt", "w", encoding="utf-8") as fh:
for rida in raporti_read:
fh.write(rida + "\r\n")
# Excel 2007
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.append([u"Esimene näit", kpv_esimene])
ws.append([u"Vimane näit", kpv_utc])
ws.append([u"Näitude arv", len(m)])
ws.append([u"Keskmine näit", average])
wb.save("raport.xlsx")
Mitmest CSV failist ajatemplite järgi info kokku lappimine üheks CSV failiks:
# -*- coding: utf-8 -*-
import os
from glob import glob # Filename globbing
from datetime import datetime, timedelta
INPUT = "p*.csv"
OUTPUT = "merged.csv"
min_kpv = None
max_kpv = None
seosed = {}
headers = []
for filename in glob(INPUT):
print u"Loen:", os.path.realpath(filename)
with open(filename) as fh:
basename = os.path.basename(filename)
basename, extension = os.path.splitext(basename)
headers.append(basename)
for rida in fh:
# Löö rida pooleks semikooloni järgi
kpv, n2it = rida.split(";")
# Parsi ajatempel
kpv = datetime.strptime(kpv, "%d.%m.%Y %H:%M")
# Nihuta min/max ajatemplit vajadusel
if not max_kpv or kpv > max_kpv: max_kpv = kpv
if not min_kpv or kpv < min_kpv: min_kpv = kpv
# Seo ujukoma näit kuupäeva ja failinimega
seosed[kpv, basename] = float(n2it)
print u"Kirjutan:", OUTPUT
kpv = min_kpv # Alusta minimaalsest kuupäevast
with open(OUTPUT, "w") as fh:
fh.write("kpv;" + ";".join(headers)+ "\n")
while kpv <= max_kpv:
fh.write("%s;" % kpv)
for basename in headers:
try:
fh.write("%.02f" % seosed[kpv,basename])
except KeyError:
pass
fh.write(";")
fh.write("\n")
# Liida ajatemplile 5 minutit juurde
kpv = kpv + timedelta(seconds=300)
# Saaks ka nii:
# kpv += timedelta(seconds=300)
Pisut kompaktsem näide kasutab csv moodulit mis hõlbustab natukene CSV failide töötlemist.
# -*- coding: utf-8 -*-
import os
import csv # CSV failide lugemise/kirjutamise moodul
from glob import glob # Filename globbing
from datetime import datetime, timedelta
INPUT = "p*.csv"
OUTPUT = "merged.csv"
min_kpv = None
max_kpv = None
seosed = {}
headers = []
for filename in glob(INPUT):
print u"Loen:", os.path.realpath(filename)
with open(filename) as fh:
basename = os.path.basename(filename)
basename, extension = os.path.splitext(basename)
headers.append(basename)
for kpv, n2it in csv.reader(fh, delimiter=";"):
# Parsi ajatempel
kpv = datetime.strptime(kpv, "%d.%m.%Y %H:%M")
# Nihuta min/max ajatemplit vajadusel
if not max_kpv or kpv > max_kpv: max_kpv = kpv
if not min_kpv or kpv < min_kpv: min_kpv = kpv
# Seo ujukoma näit kuupäeva ja failinimega
seosed[kpv, basename] = float(n2it)
print u"Kirjutan:", OUTPUT
kpv = min_kpv # Alusta minimaalsest kuupäevast
with open(OUTPUT, "w") as fh:
writer = csv.writer(fh, delimiter=";")
writer.writerow(["kpv"] + headers)
while kpv <= max_kpv:
v2ljad = map(lambda basename:seosed.get((kpv,basename), ""), headers)
writer.writerow([kpv] + v2ljad)
kpv += timedelta(seconds=300)
Important
Python 2.x versioonides olev csv moodul väljastab baite, nii et vastava tähetabeli dekodeerimine tuleb eraldi realiseerida. Python 3.x väljalasetes säärast probleemi enam pole.