NumPy massiivid
See peatükk keskendub teegile NumPy (Numerical Python). See on üks enimkasutatud Pythoni teek, mida tavaliselt kasutatakse suuremate andmehulkade töötlemiseks või teisendamiseks. Lisaks on sellega parem lahendada veidi keerulisemaid algebra ülesandeid kui mooduliga math
. Sisseehitatud on näiteks vektor- ja maatriksarvutused. Peatükis selgitatakse NumPy tähtsaimaid mõisteid ja käske. Kõik pole mõeldud kohe pähe õppimiseks - võib ka orienteeruda lõigupealkirjade järgi ja kasutada peatükki spikrina!
Ettevalmistus
Selle peatüki mõistmiseks peaks õpikust olema läbitud järjendite peatükk. Kui sul pole veel paigaldatud teek numpy
, tuleb seda nüüd teha Thonny kaudu või süsteemi käsurealt käsuga pip install numpy
. Vajadusel loe läbi õpikus moodulite paigaldamise juhised.
Massiiv
Pythoni järjend ja ennik on üles ehitatud sellisele andmetüübile, mida kutsutakse massiiviks (ingl array). Massiiv on vanem andmetüüp, mis võib koosneda ainult ühte tüüpi väärtustest, mis paiknevad mälus järjest. Pythoni standardteegis on primitiivne massiiv realiseeritud moodulis array
, aga see on üsna minimalistlik. Teek NumPy pakub sellise massiivi edasiarenduse, millel on võrreldes järjendiga järgmised omadused:
- On mõeldud ühte tüüpi väärtuste hoidmiseks.
- Elemendid paiknevad mälus järjest.
- Elementide mälukasutus on väiksem.
- Elementide lisamine ja eemaldamine on aeglasem, sest kogu massiiv tuleb mälus ümber kopeerida.
- Elementide muutmine ja suurte andmehulkade töötlemine on üldiselt palju kiirem.
NumPy optimisatsioonid
NumPy massiive ei tasu töödelda niivõrd tsüklite abil, vaid tasub kasutada nende meetodeid, sobivaid funktsioone ja indekseerimist. NumPy käsud on kiiremad, sest nad kasutavad tsükleid, mis on kirjutatud C-keeles ja kompileeritud. Lisaks jaotavad käsud töö osadeks ja operatsioonid tehakse massiivi eri osade peal paralleelselt. Kasutatakse ära erinevaid protsessori omadusi ja optimisatsioone.
Selles peatükis mõeldaksegi edaspidi massiivi all just NumPy varianti.
Massiivi kuju ja teljed
Nagu järgmisel pildil on näha, võivad massiivid olla ka mitmemõõtmelise kujuga. Mälus püsivad elemendid alati ühes reas järjest, aga esitada võib neid erineval kujul. NumPyd kasutades on väga tähtis aru saada mõistetest kuju (ingl shape) ja telg (ingl axis).
Kuju
Massiivi kuju määratakse loomishetkel, aga seda on võimalik hiljem jooksvalt muuta. Kahe rea ja kolme veeruga nullidest koosneva massiivi saab luua näiteks nii:
>>> import numpy as np >>> kuju = (2,3) >>> np.zeros(kuju) array([[0., 0., 0.], [0., 0., 0.]])
Ühemõõtmeliste massiivide puhul on kuju sama mis elementide arv:
>>> kuju = 6 >>> np.zeros(kuju) array([0., 0., 0., 0., 0., 0.])
0-mõõtmeline massiiv (punkt ehk skalaar) on põhimõtteliselt ka lubatud:
>>> np.array(np.pi) array(3.14159265)
Ühe massiivi kuju saab kätte selle muutujaga shape
:
>>> arr = np.zeros(3) >>> arr.shape (3,)
Tüüpilisemad vead, mis Numpy-ga töötades tekivad, on seotud sellega, et andmed on vale kujuga. Tihti annab NumPy veateate, aga mõnikord suudab ta ka vale kujuga midagi (ootamatut) teha. Veateate näide: massiivi kujuga 100, 2
ei saa täita kolmikutega:
>>> arr = np.full((100, 2), (3, 0.1, 2)) ValueError: could not broadcast input array from shape (3,) into shape (100,2)
Kuju muutmine
Kuna kuju muutmine ei muuda elementide paigutust mälus, siis on see operatsioon kiire. Massiivi saab ümber kujundada ainult siis, kui elemente on võimalik uuel kujul ümber paigutada:
>>> arr = np.zeros(9) >>> arr = np.reshape(arr, (3,3)) >>> arr array([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]) >>> arr = np.reshape(arr, (3,2)) ValueError: cannot reshape array of size 9 into shape (3,2)
Teljed
Ühe massiivi tasemeid või mõõtmeid nimetatakse NumPys telgedeks (ingl axes). Need on nagu mitmemõõtmelise järjendi tasemed ning järjendiga, mille esimene tase (mõõde/telg 0) koosneb alamjärjenditest, saab ka luua vastava massiivi. Mõõde või telg 1 on aga read ise, mis antud näites sisaldavad arve:
>>> järjend = [ [1,0,1], [3,2,3], [4,5,4], [7,6,7] ] >>> np.array(järjend) array([[1, 0, 1], [3, 2, 3], [4, 5, 4], [7, 6, 7]]) >>> np.array(järjend).shape (4, 3)
Sellise massiivi (või maatriksi) kuju on 4, 3
: 4 alamosa, igaühes 3 elementi. Teisisõnu, esimese telje pikkus on 4, teise telje pikkus 3.
Telgedest võib ka mõelda kui ruumi telgedest (x, y, z, ...). Siis on ehk parem ette kujutada, et teljed on nummerdatud järjekorras alates kõrgeimast mõõtmest, nii et näiteks kolmemõõtmelise massiivi puhul:
- Telg 0 on z-telg.
- Telg 1 on y-telg.
- Telg 2 on x-telg.
Suuremaid mõõtmeid võib olla raske intuitiivselt ette kujutada, aga õnneks ei lähe enamasti tarvis üle kahe mõõtme.
Indekseerimine
Massiivi indekseerimine toimib üldiselt samamoodi nagu teistegi Pythoni andmestruktuuride puhul, aga võimalusi on rohkem (ja võimsamaid!). Mitme mõõtme puhul saab kasutada näiteks komaga eraldatud indekseid või ennikuid.
>>> arr = np.array([ [1,3], [10,30], [100,300] ]) # Ülaltoodud joonisel keskel olev massiiv >>> arr[0] array([1, 3]) >>> arr[0, 0] 1 >>> arr[-1][0] 100 >>> arr[-1, 0] 100
Niimoodi saab valida ka terve veeru:
>>> arr[:,0] array([ 1, 10, 100])
Või miks mitte iga teise elemendi teises veerus:
>>> arr[::2,1] array([ 3, 300])
Elementide valimine järjendi või massiiviga
Kui kasutada indeksina järjendit või massiivi, toimib indekseerimine teistmoodi. Tagastatakse vastava telje elemendid etteantud järjekorras:
>>> arr[ [2, 0] ] # Read 2 ja 0 array([[100, 300], [ 1, 3]]) >>> arr[1, [1, 0, 1, 0, 1]] # Teise rea elemendid kohtadel 1, 0, 1, 0, 1 array([30, 10, 30, 10, 30])
Tingimustega indekseerimine
Kui massiividega loogikatehteid teha, on tulemuseks tõeväärtuste massiiv. Tuleb välja, et tõeväärtustest koosnevaid massiive saab "filtritena" kasutada:
>>> arr[arr%2 == 0] # Valib kahega jaguvad elemendid array([ 10, 30, 100, 300]) >>> arr[arr%2 == 0] = -1 # Asendab kõik kahega jaguvad elemendid >>> arr array([[ 1, 3], [-1, -1], [-1, -1]])
Mõned NumPy funktsioonid tagastavad indeksite või massiivide enniku, mida võib samamoodi indekseerimiseks kasutada. Näiteks funktsioon where
annab nende massiivi elementide indeksid, kus tõeväärtus on tõene:
>>> indeksid = np.where(arr > 10) >>> arr[indeksid] array([ 30, 100, 300])
Indekseerimine ei tee koopiat!
Kui salvestada indeksite abil mingi lõik massiivist ja selle üksikuid elemente hiljem muuta, muutub ka algne massiiv:
>>> rida1 = arr[0,:] >>> rida1[:] = np.array((-5, -10)) >>> rida1 array([ -5, -10]) >>> arr array([[ -5, -10], [ 10, 30], [100, 300]])
Operatsioonid mööda ühte telge
Käskude puhul saab üldiselt määrata, millist telge pidi käsku täita tuleks. Et mööda-telge-operatsioonidest paremini aru saada, vaatame paari käsku. Teeme selle jaoks kõigepealt sellised massiivid, nagu olid viimasel joonisel:
arr1 = np.array( [[[ 0, 1], [ 10, 11], [100, 101]], [[ 0, 1], [ 10, 11], [100, 101]], [[ 0, 1], [ 10, 11], [100, 101]]]) arr2 = np.array([ [1,3], [10,30], [100,300] ]) arr3 = np.array([4, 3])
np.sum
Väärtuste summeerimiseks on teegis olemas funktsioon sum
, ilma telge täpsustamata tagastab ta kõikide elementide summa (kõik teljed/mõõtmed kaovad, koonduvad üheks arvuks):
>>> np.sum(arr1) 1017
Mis juhtub kui liita ainult mööda kõige sügavamat telge (x-telg)? Kokkuliitmine toimub ühte telge pidi ja see telg kaob:
>>> np.sum(arr1, axis=2) array([[ 1, 21, 201], [ 1, 21, 201], [ 1, 21, 201]])
Mööda telge 1 (y-telg):
>>> np.sum(arr1, axis=1) array([[110, 113], [110, 113], [110, 113]])
Mööda telge 2 (ruumitelg z):
>>> np.sum(arr, axis=0) array([[ 0, 3], [ 30, 33], [300, 303]])
np.concatenate
Massiivide üksteise otsa liitmiseks on funktsioon concatenate
. Sellele peab andma argumendiks massiivide loendi ja massiivid ühendatakse vaikimisi mööda telge 0. Etteantud massivid peavad olema ühesuguse kujuga, v.a. sellel teljel, mida mööda liidetakse.
>>> np.concatenate( (arr2, arr2) ) # Vaikimisi mööda telge 0 array([[ 1, 3], [ 10, 30], [100, 300], [ 1, 3], [ 10, 30], [100, 300]]) >>> np.concatenate( (arr2, arr2), axis=1 ) # Mööda telge 1 array([[ 1, 3, 1, 3], [ 10, 30, 10, 30], [100, 300, 100, 300]])
Tüüpiline viga: Massiive arr2
ja arr3
ei saa kokku ühendada, sest neil pole esiteks telgede arv võrdne:
>>> np.concatenate( (arr2, arr3) ) ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
Kui aga teha massiivile arr3
näiteks üks telg juurde, saab neid mööda telge 0 kokku liita küll:
>>> arr3 = np.array( [arr3] ) >>> arr3 array([[4, 3]]) >>> np.concatenate( (arr2, arr3) ) array([[ 1, 3], [ 10, 30], [100, 300], [ 4, 3]])
np.max ja np.argmax
Suurima väärtuse leidmiseks on funktsioon max
ja vastava indeksi leidmiseks funktsioon argmax
. Esimene on veidi lihtsam:
>>> np.max(arr2) # Suurim väärtus massiivis 300 >>> np.max(arr2, axis=0) # Suurimad väärtused mööda telge 0 array([100, 300]) >>> np.max(arr2, axis=1) # Suurimad väärtused mööda telge 1 array([ 3, 30, 300])
argmax
on veidi keerulisem. Näiteks ilma telge täpsustamata tagastab ta massiivi suurima väärtuse indeksi, eeldades, et massiiv om ühemõõtmeline. Et mitmemõõtmelises massiivis vastav väärtus leida, tuleb ka massiiv kõigepealt lamedale kujule viia või kasutada funktsiooni unravel_index
:
>>> np.argmax(arr2) 5 >>> arr2.flat[5] # Vastav väärtus 300 >>> indeks = np.unravel_index(arr2.argmax(), arr2.shape) >>> arr2[indeks] 300
Kui teljeparameeter ka anda, tagastab funktsioon indeksi, mis näitab, kus suurimad väärtused sellel teljel asuvad:
>>> np.argmax(arr2, axis=0) array([2, 2], dtype=int64) >>> np.argmax(arr2, axis=1) array([1, 1, 1], dtype=int64)
Et sellele teljeindeksile vastavat väärtust kätte saada, tuleks indeksit veidi teisendada ning lõpuks kasutada funktsiooni take_along_axis
:
>>> telg = 0 >>> indeks = np.argmax(arr2, axis=telg) >>> indeks = np.expand_dims(indeks, telg) >>> np.take_along_axis(arr2, indeks, telg) array([[100, 300]])
Elementide andmetüüp
Vaikimisi on NumPy massiivides elemendid ujukomaarvudena või siis sama tüüpi, mis etteantud järjendis. Elementide tüübi saab ka täpsemalt määrata. Kasutada saab kõiki Pythoni lihttüüpe ja täisarvutüübid jaotuvad veel täpsemalt: Näiteks u1
hoiab ainult naturaalarve, mida saab esitada ühe baidi abil ehk arve 0-255. Nii saab mälu kokku hoida, kui on teada, et sellesse massiivi suuremaid ega negatiivseid väärtusi programmi töö ajal ei satu.
Ühte tüüpi saab tavaliselt mitmel moel tähistada ja tähistest saab kokku panna ka struktuurseid tüüpe. Kõik võimalikud tüübid leiad NumPy dokumentatsioonist: https://numpy.org/doc/stable/reference/arrays.dtypes.html. Siin on nimekiri tähtsamatest:
Andmetüübi nimi | Võimalikud väärtused |
---|---|
u1 | täisarvud 0 - 255 |
u2 | täisarvud 0 - 65535 |
u8 | täisarvud 0 - 2**64-1 |
i1 | täisarvud -128 - 127 |
i8 | täisarvud -2**63 - 2**63-1 |
f ehk f4 | ujukomaarvud ligikaudu -3.4e+38 - 3.4e+38 |
d ehk f8 | ujukomaarvud ligikaudu -1.8e+308 - 1.8e+308 |
S | ASCII sümbolitega sõned (baitidena) |
U | Unicode sümbolitega sõned (töötab eesti tähtedega) |
b | tõeväärtused |
O | suvalised Pythoni objektid |
NB! Kui kasutada kuskil vale andmetüüpi, ei pruugi alati veateadet näha, sest mõnel juhul suudab NumPy tüübi õigesti teisendada, teinekord aga võivad andmed hoopis muutuda:
>>> np.array([-1], "u4") array([4294967295], dtype=uint32)
Massiivi elementide andmetüüp on mõistlik määrata loomise ajal, aga seda saab ka hiljem muuta meetodiga astype
:
>>> arr = np.zeros(4) >>> arr array([0., 0., 0., 0.]) >>> arr = arr.astype("i") >>> arr array([0, 0, 0, 0], dtype=int32)
Ridadele võib isegi eraldi tüübi ja nime anda, nii et neid saab nime abil indekseerida. Näide ühest struktuursest tüübist, kus esimene rida (pealkirjaga "linn") koosneb sõnedest, teine rida ("pindala") koosneb ujukomaarvudest ja kolmas rida ("elanike arv") täisarvudest:
>>> tüüp = [("linn", "U15"), ("pindala", "f4"), ("elanike arv", int)] >>> väärtused = [ ("Tallinn", 159.3, 438341), ("Tartu", 38.8, 91407), ("Narva", 68.7, 53424), ("Pärnu", 33.2, 39605), ("Kohtla-Järve", 39.3, 32577), ("Rakvere", 10.64, 14984), ("Kuressaare", 15.5, 12933), ("Võru", 14, 11533), ("Haapsalu", 11.1, 9513) ] >>> np.array(väärtused, dtype=tüüp) array([('Tallinn', 159.3 , 438341), ('Tartu', 38.8 , 91407), ('Narva', 68.7 , 53424), ('Pärnu', 33.2 , 39605), ('Kohtla-Järve', 39.3 , 32577), ('Rakvere', 10.64, 14984), ('Kuressaare', 15.5 , 12933), ('Võru', 14. , 11533), ('Haapsalu', 11.1 , 9513)], dtype=[('linn', '<U15'), ('pindala', '<f4'), ('elanike arv', '<i4')])
Massiivi loomine
NumPy pakub mitmete operatsioonide jaoks palju erinevaid võimalusi ja käsuvariatsioone. Näiteks massiivi saab luua vähemalt 45 erineval viisil: sõnest, järjendist, failist, funktsioonist jne... Mõne käsuga saab kiiremini teatud kuju või sisuga massiivi luua:
Funktsioon | Kirjeldus |
---|---|
empty | Loob algväärtustamata massiivi. |
zeros | Loob nullidega täidetud massiivi. |
ones | Loob ühtedega täidetud massiivi. |
full | Loob etteantud väärtusega täidetud massiivi. |
full_like | Loob antud väärtusega täidetud ja antud massiivi kujuga uue massiivi. |
eye | Loob 2D massiivi, mis on mööda diagonaale ühtedega täidetud, mujal nullid. |
identity | Loob ühikmaatriksi (mööda peadiagonaali ühtedega täidetud). |
tri | Loob massiivi, kus diagonaal ja sellest ühele poole jääv ala on ühtedega täidetud. |
arange | Loob 1D massiivi, toimib nagu Pythoni range . |
linspace | Loob 1D massiivi, mis koosneb mingis vahemikus ühtlaselt jaotatud arvudest. |
random.random | Loob massiivi, mis on täidetud juhuarvudega vahemikust [0,1). |
random.standard_normal | Loob massiivi, mis on valim juhuslikust normaaljaotusest. |
Tehted massiividega
Massiividega tehete tegemise on NumPy väga mugavaks teinud:
>>> arr1 = np.arange(4) # [ 0, 1, 2, 3] >>> arr2 = np.arange(10, 10+4) # [10,11,12,13] >>> >>> arr1 + arr2 array([10, 12, 14, 16]) >>> arr1 - arr2 array([-10, -10, -10, -10]) >>> arr1 * arr2 array([ 0, 11, 24, 39]) >>> arr1 * 300 array([ 0, 300, 600, 900])
Maatriksite ja vektorite korrutised
Kasutusel on ka operaator @, mida Pythonis arvude vahel ei kasutata. See annab NumPys vektorite skalaarkorrutise või maatriksite korrutise:
>>> arr1 @ arr2 # Vektorite skalaarkorrutis 74 >>> arr1 = arr1.reshape((2,2)) # [ [0, 1], [2, 3] ] >>> arr2 = arr2.reshape((2,2)) # [ [10, 11], [12, 13] ] >>> arr1 @ arr2 # Maatriksite korrutis array([[12, 13], [56, 61]]) >>>
Vektorkorrutiseks tehtemärki eraldatud ei ole, kasutada tuleb funktsiooni cross
.
Kõrgem matemaatika
NumPys on olemas vahendid ka veidi keerulisema algebraga tegelemiseks, näiteks determinantide arvutamiseks ja võrrandisüsteemide lahendamiseks. Need asuvad moodulites:
Moodul | Sisu |
---|---|
linalg | Lineaaralgebra |
polynomial | Polünoomidega arvutamine |
fft | Fourier' teisendused |
Funktsiooniga linalg.det
saab ruutmaatriksite determinante leida. Võrrandisüsteemide lahendamiseks on aga mõistlik kasutada funktsiooni linalg.solve
, millele tuleb parameetriks anda võrrandite liikmete kordajate maatriks ja vabaliikmete vektor. Näiteks järgmine võrrandisüsteem:
{$ \large\left\{\begin{array}{@{}l@{}}
2x_0 + 3x_1 = -2\\
-x_0 + \frac{1}{4}x_1 = 8
\end{array}\right. $}
Selle lahendid on {$ x_0=-7, x_1=4 $}:
>>> kordajad = [[2, 3], [-1, 1/4]] >>> vabaliikmed = [-2, 8] >>> np.linalg.solve(kordajad, vabaliikmed) array([-7., 4.])
Et polünoomidega arvutada, tuleb need kõigepealt luua:
>>> kordajad = [8, 0, -2] # -2x**2 + 8 >>> p = np.polynomial.Polynomial(kordajad)
Polünoomile 'p' vastab ruutvõrrand {$ -2x^2 + 8 = 0 $}. Meetodite abil saab nüüd leida polünoomi nullkohti, tuletisi ja integraale:
>>> p.roots() # Nullkohad (lahendid) array([-2., 2.]) >>> p.deriv(1) # Esimene tuletis Polynomial([ 0., -4.], domain=[-1., 1.], window=[-1., 1.]) >>> p.deriv(1).integ(1) # Tuletise esimene määramata integraal Polynomial([ 0., 0., -2.], domain=[-1., 1.], window=[-1., 1.])
Loogilised tehted
Mõned loogilised tehted annavad tõeväärtuste massiivi. Võrrelda saab massiive nii arvude kui üksteisega:
>>> arr1 = np.zeros(5, dtype="u1") >>> arr2 = np.ones(5, dtype="u1") >>> arr1 < arr2 array([ True, True, True, True, True]) >>> arr1 == arr2 array([False, False, False, False, False]) >>> ~arr1 # not([0, 0, 0, 0, 0]) array([ True, True, True, True, True])
Täisarvude või tõeväärtuste massiividega saab teha ka bititehteid:
>>> arr1 = arr1.astype(bool) >>> arr2 = np.array([True, False, True, False, True]) >>> arr1 & arr2 # AND array([False, False, False, False, False]) >>> arr1 | arr2 # OR array([ True, False, True, False, True]) >>> arr2 ^ True # XOR array([False, True, False, True, False]) >>> arr2 ^ 1 array([0, 1, 0, 1, 0], dtype=int32)
Failist ja faili
Massiivi saab õigesti vormistatud tekstifailist ühe käsuga sisse lugeda:
159;438341 38;91407 68;53424 33;39605
>>> np.genfromtxt("fail.txt", dtype=int, delimiter=";") array([[ 159, 438341], [ 38, 91407], [ 68, 53424], [ 33, 39605]])
Kui failis on reaalarvud, tuleks parameeter dtype
vastavalt valida. Parameetritega missing_values
ja filling_values
on võimalik muuta seda, kuidas puuduvate väärtustega käitutakse.
Massiivi saab tekstifaili salvestada funktsiooniga savetxt
. Käskudega save
ja load
on võimalik massiive salvestada ja sisse lugeda NumPy-spetsiifilises failivormingus:
>>> np.save("array.npy", arr) >>> arr = np.load("array.npy")
Parameetreid saad täpsemalt uurida dokumentatsioonist vastavate funktsioonide alt: https://numpy.org/doc/stable/reference/routines.io.html.
Kui on tarvis lugeda andmeid näiteks tabelkujul failidest, siis on mõistlikum kasutada teeki pandas
, mis on just selle jaoks mõeldud ja toimib NumPyle väga sarnaselt.
Käskude kokkuvõte ja spikker
Kui massiivi loomiseks oli juba tohutult võimalusi, siis võib eeldada, et funktsioonide ja meetodite arv NumPys on päris suur. Siin on veel mõned, mida tasub ära mainida:
Elemendikaupa töötavad funktsioonid | |
---|---|
abs | Arvutab massiivi (iga elemendi) absoluutväärtuse. |
add | Liidab massiivid elemendikaupa nagu vastava tehtega, aga argumentidega saab käitumist rohkem juhtida. |
add.accumulate | Liidab massiivid elemendikaupa kumulatiivselt. |
apply_along_axis | Rakendab etteantud funktsiooni mööda telge. |
array_equal | Tagastab True , kui massiivide kuju ja elemendid on võrdsed, muidu False . |
gcd | Leiab sama kujuga massiivide vastavate elementide suurimad ühisnimetajad. |
corrcoef | Tagastab kuni kahemõõtmelis(t)e massiivi(de) Pearsoni korrelatsioonikordajate maatriksi. |
gradient | Tagastab massiivi gradiendi. |
isclose | Võtab parameetriks kaks massiivi ja tagastab sama kujuga tõeväärtuste massiivi, kus iga element ütleb, kas antud massiivide elemendid sellel kohal on võrdsed mingi hälbe piires. |
sin | Arvutab massiivi (iga elemendi) siinuse. |
Massiivi kuju või suurust töötlevad funktsioonid | |
array_split | Tükeldab massiivi. |
concatenate | Ühendab massiivid. |
delete | Kustutab massiivist elemente, tagastab uue massiivi. |
expand_dims | Lisab massiivi uue telje, tagastab paisunud kujuga massiivi. |
flip | Tagastab massivi peegeldatud kuju. |
insert | Sisestab massiivi väärtused, tagastab uue massiivi. |
packbits | Pakib kahendarvude massiivi bittidena i1 tüüpi massiiviks. |
pad | Täidab massiivi mingeid külgi pidi mingi(te) väärtustega. Nt. loob pildile raami. |
repeat | Dubleerib massiivi elemente. Tagastab paisunud massiivi. |
resize | Tagastab uue kuju ja suurusega massiivi. |
roll | Tagastab ühte telge pidi nihutatud massiivi. Viimased väärtused lähevad esimeseks. |
rot90 | Tagastab 90 kraadi pööratud massiivi. |
swapaxes | Vahetab massiivi kaks telge omavahel, tagastab uue massiivi. |
tile | Dubleerib massiivi mingi arv kordi mingite telgede suunas. |
Otsingufunktsioonid | |
searchsorted | Annab sorteeritud massiivi puhul indeksid, kuhu antud elemendid sisestada tuleks, et järjestatus säiliks. |
unique | Tagastab kõik massiivis esinevad erinevad väärtused kasvavas järjekorras. |
where | Tagastab tingimuse (filtri) põhjal indeksid, kus tingimus kehtib. Kui anda lisaargumentideks 2 massiivi, valib tõese indeksi puhul väärtused ühest massiivist, muidu teisest. |
Hulgatehted massiividega (vt. ka funktsiooni unique ) | |
isin | Võtab parameetriks kaks massiivi ja tagastab esimese massiivi kujuga tõeväärtuste massiivi, kus iga element ütleb, kas esimese massiivi vastav element leidus teises massiivis. |
union1d | Tagastab massiivide ühendi. |
intersect1d | Tagastab massiivide ühisosa. |
setdiff1d | Tagastab elemendid esimesest massiivist, mida teises pole (vahe). |
setxor1d | Tagastab elemendid, mida mõlemas massiivis pole (sümmeetriline vahe). |
Paljud funktsioonid on saadaval ka massiivimeetoditena, aga kui kasutada mõlemaid, siis tasub tähele panna, et funktsioonid tagastavad üldjuhul massiivi muudetud koopia, aga mõned meetodid muudavad olemasolevat massiivi (tabelis ära märgitud). Näiteks massiiv.sort
sorteerib massiivi, aga np.sort
võtab parameetriks massiivi ja tagastab selle sorteeritud koopia. Teatud käskudel on parameeter inplace
, mis seda käitumist muudab. Näited erinevatest meetoditest:
Meetod | Kirjeldus |
---|---|
astype | Muudab massiivi elementide tüübi (tagastab koopia). |
clip | Asendab kõik ülem-/alampiirist suuremad/väiksemad elemendid piirväärtusega. |
fill | Asendab massiivis kõik väärtused ühe väärtusega (ei tagasta, muudab). |
flatten | Tagastab massiivi ühemõõtmelisel kujul. |
max | Tagastab massiivi suurima elemendi. |
min | Tagastab massiivi väikseima elemendi. |
mean | Tagastab massiivi elementide keskmise. |
nonzero | Tagastab indeksid, kus olev väärtus pole 0. |
ptp | Peak-to-peak: Tagastab massiivi suurima ja vähima elemendi vahe. |
repeat | Dubleerib massiivi elemente. |
resize | Muudab massiivi suurust ja kuju (ei tagasta, muudab; parem on kasutada vastavat funktsiooni). |
reshape | Tagastab muudetud kujuga massiivi. |
round | Ümardab massiivi elemendid. |
sort | Sorteerib massiivi (muudab massiivi, vaikimisi mööda viimast telge). |
squeeze | Eemaldab massiivist teljed, mille pikkus on 1. |
sum | Tagastab elementide summa. |
trace | Tagastab diagonaali(de) elementide summa. |
transpose | Tagastab transponeeritud massiivi. |
tofile | Kirjutab massiivi faili. |
tolist | Teisendab massiivi järjendiks. |
Igal massiivil on järgmised muutujad:
Muutuja | Kirjeldus |
---|---|
shape | Massiivi kuju. |
size | Massiivi elementide arv. len(massiiv) annab ainult 0-telje pikkuse. |
itemsize | Ühe elemendi pikkus baitides. |
dtype | Elementide tüüp. |
ndim | Massiivi mõõtmete või telgede arv. |
T | Massiiv transponeeritud kujul. |
Siin juhendis me NumPy mooduleid lähemalt ei uuri, aga hea on teada, milliseid mooduleid NumPys veel leidub:
Teegiga töötades on hea dokumentatsiooni või spikrit kõrval hoida. Dokumentatsiooni algus on siin: https://numpy.org/doc/stable/reference/index.html
Siinset silmaringimaterjali võib kasutada spikrina. Rohkem spikreid tasub otsida märksõnaga NumPy cheatsheet. Järgnevalt lingilt leiab ühe variandi: https://www.datacamp.com/cheat-sheet/numpy-cheat-sheet-data-analysis-in-python.
Andmeteadus ja masinõpe
NumPyd täiendavad või kasutavad alusena ka mitmed teised teegid, eriti need, mis on seotud andmeteadusega. NumPy tundmine teeb nendega töötamise ka oluliselt kergemaks. Tihti nende teekide funktsioonid tagastavad või võtavad parameetriks ka NumPy massiive.
Matplotlib
on teek, mis on mõeldud andmete visualiseerimiseks, jooniste tegemiseks ja kuvamiseks.Seaborn
sisaldab rohkem huvitavamaid kujutamisvõimalusi.Pandas
on mõeldud tabelandmete sisselugemiseks, töötlemiseks ja analüüsimiseks.Scipy
sisaldab palju teaduslikke funktsioone: keerulisemad matemaatilised tehted, andmete klasterdamine, helisignaali ja pilditöötluse funktsioonid, integreerimine ja võrrandite lahendamine.Sklearn
pakub mugavalt kasutatavaid masinõppe algoritme.Keras
pakub rohkem sügavõppe algoritme.PyTorch
on veel üks sügavõppe teek. Kiirem, aga keerulisem kasutada kuiKeras
.
Põhjalikumalt saab nende teekidega tutvuda andmeteadust või tehisintellekti käsitlevatel kursustel, näiteks:
- LTAT.01.003 Tehisintellekt
- LTAT.02.017 Tehisintellekti algkursus
- LTAT.02.002 Sissejuhatus andmeteadusesse
Enesekontrolliküsimused
Ülesanded
1. Koosta programm, mis küsib kasutajalt sisendiks kaks maatriksit või vektorit ning kuvab vastusena nende
- skalaarkorrutise
- vektorkorrutised
- vastavate elementide lihtsamate aritmeetiliste tehete tulemused: summa, vahe, korrutis, jagatis
- ühisosa elemendid
Kui mõnda tehet või operatsiooni ei saa mingil põhjusel teha, tuleb kasutajale põhjus väljastada!
2. Järgmiselt veebilehelt leiab 101 NumPy teisendusharjutust, proovi mõningaid lahendada: https://www.machinelearningplus.com/python/101-numpy-exercises-python/.
3. Kirjuta programm, mis küsib kasutajalt tabelifaili (nt. Exceli või CSV-failid) nime ja loeb faili sobivasse NumPy massiivi. Seejärel võiks programm väljastada parameetreid ja infot andmete kohta. Näiteks:
- Ridade/veergude keskmised väärtused
- Enimesinevad väärtused
- Suurimad, vähimad väärtused
- Ridade/veergude väärtuste korrelatsioonid, seosed
- Väärtuste osakaalud
Vali lisaks NumPyle veel vähemalt üks andmeteaduse teek, mida selles ülesandes ära kasutada saaksid. Ideed:
- Kujuta andmeid ja nende seoseid. Uuri huvitavaid kujutamisvõimalusi: Top 50 matplotlib Visualizations.
- Kui sul on palju andmeid (100 000+ rida), proovi üks väärtusi ennustav masinõppe mudel treenida.
4. Vaata, kas oled kirjutanud mõne programmi, mis töötleb järjendite abil suurt hulka andmeid, näiteks pilte või heli. Asenda järjendid nüüd sobivates kohtades NumPy massiividega ja proovi, kas see teeb programmi efektiivsemaks.