Rividata datatieteilijän arjessa
Rividata on datatieteilijän arjen yksi tunnusomaisimmista piirteistä. Excel-taulukot, CSV-tiedostot, tietokantataulut rakentuvat samalle periaatteelle: rivejä ja sarakkeita. Rivillä on yksi havainto ja muuttujat ovat sarakkeissa. Ja tätä dataa käsitellään tavallisesti pandas-paketilla.
Rividata vs monidimensionaalinen data
Olen viime ajat työskennellyt säädatan parissa. Säädataa ovat esimerkiksi erilaisten säämallien tuottama säännöllinen ruudukkodata ja havaintodata. Ja säädatan käsittely rividatana on erittäin hankalaa. Yksittäinen lämpötilamittaus ei ole vain numero – se on numero tietyssä paikassa, tietyssä korkeudessa, tiettynä ajanhetkenä. Se elää neljässä dimensiossa:
- Leveysaste (latitude)
- Pituusaste (longitude)
- Korkeus (esim. hybridipainetasot)
- Aika (temporal)
Sama pätee sekä mallidataan (ennustemallit, reanalyysit) että havaintodataan (satelliitit, tutkat, sääasemat). Datan luonnollinen rakenne on monidimensionaalinen ruudukko, ei rivitaulukko.
Säädata voidaan teknisesti ajateltuna pakottaa rividataksi - laittamalla jokaiselle riville muuttujat leveysaste, pituusaste, korkeus ja aika. Mutta sen käsittely rividatana on äärimmäisen epäkäytännöllistä.
Monidimensionaalisen datan hankaluus rividatana
Ajatellaan tilannetta, jossa monidimensionaalista dataa käsitellään väkisin rividatana:
Indeksointi on hankalaa. Jos haluat lämpötilan pisteessä (60°N, 25°E, 850 hPa, 2024-01-15T12:00) rividatasta, niin Pandasissa kirjoittaisit:
df[(df.lat == 60) & (df.lon == 25) & (df.level == 850) & (df.time == '2024-01-15T12:00')]
Hyi olkoon!
Jokainen haku vaatii koko taulukon läpikäynnin. Rividatassa ei ole dimensioiden määrittämää rakennetta. Kun haet yhden pisteen, niin Pandas käy läpi koko taulukon. Ja jos haluat datalle indeksit, niin tarvitset moni-indeksit.
Dimensioiden tuottama redundanssi vie muistia! Jokaisella rivillä toistetaan koordinaatit. Miljardi mittauspistettä tarkoittaa miljardia kertaa samat lat/lon/time/level-arvot.
Spatiotemporaaliset operaatiot ovat kamalia. "Hae naapuripisteet", "laske gradientti" ja "interpoloi" vaativat monimutkaisia self-joineja.
Dimensioaggregaatiot vaativat groupby-akrobatiaa. "Laske keskiarvo ajassa jokaiselle pisteelle" on rividatassa groupby-operaatio.
Xarray pelastaa datatieteilijän
Xarray ratkaisee edellä kuvatut ongelmat nimetyillä dimensioilla ja koordinaateilla:
Indeksointi on luonnollista. Sama haku kuin edellä:
ds.temperature.sel(time='2024-01-15T12:00', level=850, lat=60, lon=25)
Kompaktia. Ei boolean-maskeja, ei mystisiä indeksinumeroita.
Haut ovat nopeita. Xarray tietää datan rakenteen ja löytää oikean solun suoraan koordinaattien perusteella.
Muistinkäyttö on tehokasta. Koordinaatit tallennetaan kerran ja data säilyy tiiviissä taulukkomuodossa (taulukossa enemmän kuin 2 dimensiota).
Spatiotemporaaliset operaatiot ovat sisäänrakennettuja. Interpolointi, naapurihaut ja gradientit toimivat luontevasti dimensioiden yli.
Dimensioaggregaatiot ovat yksinkertaisia:
ds.temperature.mean(dim='time') # Keskiarvo ajassa
ds.temperature.mean(dim=['lat', 'lon']) # Spatiaalinen keskiarvo
Koodi on luettavaa ja ymmärrettävää kuukauden tai vuoden päästä.
Mutta entä data- ja koneoppimisinsinöörit?!
Vaihdetaan näkökulma datatieteestä dataan liittyvään insinöörityöhön: niihin asioihin, jotka kiinnostavat datainsinöörejä, MLOpseja ja sellaisia.
Rividatan prosessointiin ja prosessoinnin skaalamiseen on useita toimivia ratkaisuja. Esimerkiksi Databricks ja Spark ovat kypsä ekosysteemi: niissä datan tallennus ja laskenta on erotettu toisistaan. Ja niinpä voit tallentaa huimia määriä dataa maksamatta itseäsi kipeäksi. Ja kun jotakin tarvitsee laskea, voit allokoida oikean mahtiklusterin, joka laskee teratavujen lähdedatasta pyydetyt arvot minuuteissa. Maksat vain siitä ajasta, jonka klusteri tarvitsee laskennan suorittamiseen.
Mutta entä monidimensionaalinen data? Millaisia työkaluja ja menetelmiä on monidimensionaalisen datan prosessointiin ja prosessoinnin skaalaamiseen?
Databricks ja Spark ovat rividatan työkaluja ja ne ongelmat, jotka datatieteilijä kohtaa monidimensionaalisessa datassa kertautuvat laskenta-alustoja pyörittävien datainsinöörien työssä. Huumasta huolimatta, Databricks ja Spark eivät suoraan sovellu monidimensionaalisen datan prosessointiin.
Miten Dask palvelee datainsinöörejä
Vastaus monidimensionaalisen data prosessoinnin skaalaamisen ongelmiin on Dask. Kyse on laskennan rinnakkaistamisesta ja klusterien hyödyntämisestä.
Ajattele tuttua NumPy-taulukkoa. Pienessä datassa on yksi taulukko, joka mahtuu yhden koneen muistiin ja jota prosessoidaan lokaalisti. Dask laajentaa tämän klusteriin: iso data jaetaan moneen NumPy-taulukkoon, jotka yhdessä muodostavat koko datan. Klusterin koneet prosessoivat palasia rinnakkain. Ja Dask yhdistää osatulokset kokonaisuudeksi. Ja koko laskennan ajan käyttäjä näkee datan yhtenä taulukkona.
Tämä ratkaisee datainsinöörin skaalausongelmat:
- Indeksointi ja haut: Dask säilyttää nimetyt dimensiot ja koordinaattipohjaisen haun myös teratavujen datassa
- Muistiongelma: Dask ei lataa kaikkea muistiin, vaan prosessoi pala kerrallaan
- Spatiotemporaaliset operaatiot: Toimivat samalla syntaksilla kuin pienessä datassa
- Dimensioaggregaatiot:
ds.temperature.mean(dim='time')toimii, vaikka dataa olisi massiivisesti, vaikkapa 40 vuoden ajalta
Chunkkaus ja rinnakkaistaminen
Kuvittele datasi: leveysaste × pituusaste × korkeus × aika. Dask jakaa tämän hyperkuution pieniksi chunkeiksi – kukin chunkki on yksi NumPy-taulukko, esimerkiksi 100×100 pistettä yhden vuorokauden ajalta. Jokainen chunkki on riittävän pieni prosessoitavaksi yhdellä ytimellä.
Sen jälkeen Dask rinnakkaistaa saman operaation jokaiselle chunkille. Jos kysyt vaikkapa muuttujan keskiarvoa ajassa, niin Dask laskee sen jokaiselle NumPy-taulukolle erikseen ja yhdistää tulokset.
Laskentagraafi
Perinteisessä imperatiivisessa ohjelmoinnissa jokainen rivi suoritetaan välittömästi. Dask toimii toisin: se rakentaa laskentagraafin, joka ainoastaan kuvaa operaatioiden väliset riippuvuudet. Vasta kun pyydät tulosta, graafissa määritelty laskenta suoritetaan.
# Lazy-evaluointi - ei laske vielä mitään, vaan rakentaa graafin
result = ds.temperature.mean(dim='time')
# Compute käynnistää laskennan koko klusterissa
result.compute()
Laskentagraafi mahdollistaa älykkäät optimoinnit: järjestelmä näkee koko putken kerralla ja voi suunnitella suorituksen optimaalisesti. Databricks/Spark -ekosysteemissä optimointia on tehty paljon mutta Dask-laskennan optimoinnissa on vielä paljon työtä.
Työkalujen kypsyystaso
Xarray on kypsä, vakaa ja tuotantokelpoinen työkalu. Dokumentaatio on kattava, yhteisö aktiivinen, edge caset tunnettuja.
Dask on lupaava ja toimiva, mutta kehittymättömämpi. Siltä puuttuu vielä se, minkä Databricks toi Delta Lakeen: valmiin, hallitun ja optimoidun ekosysteemin. Dask-klusterien hallinnossa, chunkkausstrategioiden optimoinnissa ja memory managementissa on tekemistä. Automaattinen klusteri-skaalaus, älykkäät chunkkausstrategiat, transaktionaalisuus – näitä rakennetaan pala kerrallaan yhteisön voimin.
Optimointien puute
Databricks ja Spark hyödyntävät laskentagraafin mahdollistamia automaattisia optimointeja aggressiivisesti: tarpeettomien sarakkeiden karsinta, datan skippaus metadata-filtteröinnillä, ja muita optimointeja työnnetään graafin alkuun (predicate pushdown). Nämä vähentävät prosessoitavan datan määrää dramaattisesti.
Tämä oli minulle yksi kipukohdista, koska olin tottunut ajatukseen, että laskenta-alusta on niin fiksu, että se osaa optimoida operaatioitaan heuristisesti. Mutta Daskissa datan rajaaminen, välimuistitus ja muut vastaavat toimenpiteet täytyy itse kirjoittaa laskentakoodiin eksplisiittisesti. Vastuu on vielä käyttäjällä.
Käytännössä tämä tarkoittaa, että Dask vaatii enemmän käsityötä ja ymmärrystä. Mutta kun sen saa toimimaan, tulokset ovat vaikuttavia: samaa koodia voi ajaa kannettavalla ja sadoilla ytimillä pilvessä, vain konfiguraatiota muuttamalla.
Lopuksi
Jos työskentelet monidimensionaalisen datan parissa – säähavainnoilla, satelliittikuvilla, ilmastomalleilla – Xarray ja Dask tarjoavat parhaan tällä hetkellä saatavilla olevan työkaluketjun (laita viesti jos olen väärässä!). Xarray tekee koodista luettavaa ja ylläpidettävää. Dask mahdollistaa skaalautumisen teratavuihin.
Polku ei ole aina sileä. Daskin kanssa joutuu vielä säätämään enemmän kuin Databricksin kanssa. Mutta yhteisö kasvaa, työkalut kehittyvät, ja monelle organisaatiolle tämä on ainoa realistinen tapa käsitellä modernin ilmastotieteen ja kaukokartoituksen datamääriä.
Ja tärkeintä: data säilyy siinä muodossa, jossa sen pitää olla – monidimensionaalisena, indeksoitavana, ymmärrettävänä.