Vernier andmekoguja võib anda sellise tekstifaili,
kuhu on kirjutatud
üksteise järel mitu massiivi (koos päisega). Selliseid andmeid saab endiselt lugeda funktsiooniga
pandas.read_csv
, kui kasutada parameetreid skiprows
ja nrows
. Esimene näitab, mitu rida faili alguses
ära jätta, ja teine näitab, mitu sellele järgnevat rida lugeda. Oletagem
näiteks, et meil on teada esimese ja viimase rea järjekorranumbrid
(seda võib järgi vaadata mõne reanumbreid näitava koodiredaktoriga, nagu
Notepad++).
from pandas import read_csv
def laadi_katse(fail, read, veerud=(0,1)):
esimene, viimane = read
return read_csv(fail,
skiprows = esimene - 1,
nrows = viimane - esimene + 1,
decimal = ',',
delimiter = '\t',
usecols = veerud,
dtype = float,
header = None).values
andmed = laadi_fail('andmed.txt', (8, 5008), (0, 1, 2))
On ka mõeldav, et mõni andur ei suuda nõutud kiirusega mõõta. Sel juhul
vastavas andmetulbas on mingi osa andmevälju tühjad. read_csv
endiselt suudab lugeda selle massiivi
arvulisel kujul, aga nendel kohtadel, kus andmed puuduvad, saab olema
spetsiaalväärtus NaN (Not a Number). Need
read tuleb kõrvaldada, kontrollides selle tulba elemente näiteks funktsiooniga
np.isfinite
. Oletagem näiteks, et puuduvad väärtused on kolmandas
tulbas (ehk tulbas indeksiga 2):
olemas = np.isfinite(andmed[:,2])
andmed = andmed[olemas]
Kõige eelneva asemel võib muidugi programmeerida ka spetsiaalse funktsiooni sellise faili parsimiseks. Sel juhul enam massiivi alguse- ja lõpu ridu pole tarvis järgi vaadata, peab teadma vaid katse nime.
def laadi_katse(fail, nimi, veerud=(0,1)):
min_väljade_arv = max(veerud) + 1
with open(fail, encoding='utf-8') as f:
while True:
rida = f.readline()
if rida == '\n': # tühi rida
continue
if rida.rstrip() == nimi: # õige massiiv leitud
break
if rida == '': # faili lõpp
raise RuntimeError(f"Katset '{nimi}' ei leitud")
for i in range(4): # veel 4 päiserida vahele jätta
f.readline()
tulemus = []
while True:
rida = f.readline()
if rida == '\n' or rida == '' or rida.startswith('Vernier Format'):
return np.array(tulemus)
rida = rida[:-1] # eemaldame rea lõpu sümboli
väljad = rida.split('\t')
if len(väljad) < min_väljade_arv:
raise RuntimeError(f"Reas '{rida}' on vaid {len(väljad)} andmevälja, aga vaja on {min_väljade_arv}")
if any(väljad[i] == '' for i in veerud): # mõne anduri lugem puudu, ignoreerime rida
continue
tulemus.append([float(väljad[i].replace(',', '.')) for i in veerud])
andmed = laadi_katse('andmed.txt', 'Mõõtmine 1', (0, 1, 2))
NB! Kuna fail võib sisaldada Eesti täpitähti, on oluline kasutada õiget kodeeringut (UTF-8, mitte ASCII).