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).

Vaata lisaks

Sisukord