Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Osnove modula numpy

Modul numpy namestimo z upravljalnikom paketov pip z naslednjim ukazom (v kolikor ga še nimamo nameščenega):

pip install numpy

oz. paket posodobimo na najnovešo različico:

pip install numpy --upgrade

Najprej uvozimo modul (uveljavljeno je, da ga uvozimo v kratki obliki np):

Gre za enega najbolj pomembnih modulov. Na kratko: gre za visoko optimiran modul za numerične izračune; zelo dobri tutoriali so zbrani na naslovu: github.com/numpy/numpy-tutorials. Za odličen uvod v Numpy si lahko ogledate YouTube posnetek: NumPy Tutorial (2021): For Physicists, Engineers, and Mathematicians

Poglejmo si najprej sintakso za vektor ničel (dokumentacija):

numpy.zeros(shape, dtype=float, order='C')

argumenti so:

  • shape definira obliko (lahko večdimenzijsko numerično polje),

  • dtype definira tip podatka,

  • order definira vrstni red (lahko je C ali F kot Fortran).

Poglejmo primer:

array([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]])

ali pa:

array([[0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.]])

Podobno kot zeros se obnaša ones, vendar je namesto ničel vrednost 1 (dokumentacija).

Poglejmo si primer, kjer definiramo tudi tip int (privzeti tip je float):

array([1, 1, 1, 1])

Pogosto bomo tudi uporabljali razpon vrednosti arange (dokumentacija):

numpy.arange([start, ]stop, [step, ]dtype=None)

kjer so argumenti:

  • start začetna vrednost razpona (privzeto 0),

  • stop končna vrednost razpona,

  • step korak in

  • dtype tip vrednosti (če tip ni podan, se določi iz ostalih argumentov).

Poglejmo primer razpona od 0 do 9 (kakor vedno pri Pythonu od je vključen, do pa ni):

array([0, 1, 2, 3, 4, 5, 6, 7, 8])

ali pa od 7 do 12 po koraku 2, vendar število s plavajočo vejico:

array([ 7., 9., 11.])

Še eno funkcijo bomo pogosto uporabili, to je linspace (dokumentacija):

numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

ki definiranemu razponu vrne numerično polje vrednosti na enaki razdalji (ekvidistanten razmik).

Argumenti so:

  • start začetna vrednost razpona,

  • stop končna vrednost razpona,

  • num število točk/vozlišč,

  • endpoint ali je vrednost pri stop vključena ali ne,

  • retstep v primeru True vrne funkcija terko (rezultat, korak)

  • dtype tip vrednosti (če tip ni podan, se določi iz ostalih argumentov).

Primer generiranja 10 točk na razponu od −π-\pi do vključno +π+\pi:

array([-3.14159265, -2.44346095, -1.74532925, -1.04719755, -0.34906585, 0.34906585, 1.04719755, 1.74532925, 2.44346095, 3.14159265])

Mimogrede smo zgoraj spoznali, da ima numpy vgrajene konstante (npr. π\pi):

Poglejmo še vgrajene funkcije za generiranje naključnih števil. Te najdemo v numpy.random (dokumentacija).

Najprej si poglejmo funkcijo numpy.random.seed(), ki se uporablja za ponastavitev generatorja naključnih števil (dokumentacija). To pomeni, da lahko z istim semenom (angl. seed) različni uporabniki generiramo ista naključna števila!

Opomba: funkcije numpy.random.seed(), rand(), random(), normal() itd. spadajo v starejši (legacy) vmesnik, ki še vedno deluje. Sodobni pristop je, da si ustvarimo lasten generator in kličemo njegove metode (dokumentacija):

rng = np.random.default_rng(0)   # seme 0
rng.random(3)                    # enakomerna porazdelitev na [0, 1)
rng.normal(size=3)               # normalna porazdelitev

Spodnja vrstica:

bo povzročila, da bo klic generatorja naključnih števil z enakomerno porazdelitvijo numpy.random.rand() (dokumentacija) vedno rezultiral v iste vrednosti:

array([0.5488135 , 0.71518937, 0.60276338])

Preizkusimo ali je res, kar smo zapisali, in ponastavimo seme in kličimo generator:

array([0.5488135 , 0.71518937, 0.60276338])

Zapis matrik in vektorjev

Matrika je dimenzije m x n, kjer je na prvem mestu m število vrstic in n število stolpcev. Primer definiranja matrike dimenzije m x n = 3 x 2 je:

array([[0., 0.], [0., 0.], [0., 0.]])

Vektor je lahko zapisan kot vrstični vektor:

array([0., 0., 0.])

ali kot stolpični vektor:

array([[0.], [0.], [0.]])

V modulu numpy lahko vektorje in matrike zapisujemo kot:

Priporočena je prva oblika (numpy.array), ki pa ne sledi povsem matematičnemu zapisu (več o tem pozneje), nam pa omogoča enostavnejše programiranje in je tudi numerično bolj učinkovit pristop (vir). Pristopa numpy.matrix tukaj ne bomo obravnavali.

V angleškem jeziku bomo array prevajali kot večdimenzijsko numerično polje ali včasih večdimenzijske sezname (ker imajo nekatere podobnosti z navadnimi seznami). Nekatere knjige array tukaj prevajajo kot tabela.

Rezanje

Rezanje (angl. slicing) seznamov smo si že pogledali v poglavju Uvod v Python. Podobno rezanje, vendar bolj splošno, velja tudi za numerična polja modula numpy.

Sintaksa rezanja (dokumentacija) je:

numpy_array[od:do:korak]

pri tem velja:

  • indeksiranje se začne z 0 (kot sicer pri Pythonu),

  • od pomeni >=,

  • do pomeni <,

  • od, do, korak so opcijski parametri,

  • če parameter od ni podan, pomeni od začetka,

  • če parameter do ni podan, pomeni do vključno zadnjega,

  • če parameter korak ni podan, pomeni korak 1.

Primer od elementa 3 do elementa 8 po koraku 2:

array([3, 5, 7])

Primer od elementa 3 naprej:

array([3, 4, 5, 6, 7, 8, 9])

Primer od elementa 3 naprej, vendar vsak tretji:

array([3, 6, 9])

Primer zadnjih 5 elementov, vendar vsak drugi:

array([5, 7, 9])

Primer zadnjih 5 elementov brez zadnjih 2, vendar vsak drugi:

array([5, 7])

Rezanje večdimenzijskega numeričnega polja

Večdimenzijsko rezanje izvedemo tako, da dimenzije ločimo z vejico:

numpy_array[rezanje0, rezanje1,...]

kjer rezanje0 reže indeks 0 (prvo dimenzijo) v obliki od:do:korak, rezanje1 reže indeks 1 (drugo dimenzijo) in tako naprej.

Poglejmo si primer; najprej pripravimo seznam 15 števil (np.arange), nato z metodo reshape() (dokumentacija) spremenimo obliko v matriko 3 x 5:

array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])

Obliko numeričnega polja lahko preverimo z atributom shape (dokumentacija).

(3, 5)

Atribute bomo sicer podrobno spoznali pri obravnavi razredov.

Prikažimo vrstice z indeksom 0:

array([0, 1, 2, 3, 4])

Isti rezultat bi dobili s prikazom vrstice z indeksom 0 in vseh stolpcev:

array([0, 1, 2, 3, 4])

Pogosto želimo dostopati do stoplcev, npr. stolpca z indeksom 1 (torej režemo vse vrstice in stolpec z indeksom 1):

array([ 1, 6, 11])

Poglejmo si še primer rezanja prvih dveh vrstic in zadnjih dveh stolpcev:

array([[3, 4], [8, 9]])

Podobna logika se uporabi pri dimenzijah višjih od 2.

Operacije nad numeričnimi polji

Poglejmo si sedaj bolj podrobno nekatere osnovne prednosti numeričnega polja numpy.array v primerjavi z navadnim seznamom Python.

Najprej pripravimo navaden Pythonov seznam:

[1, 2, 3, 4, 5, 6, 7]

In nato še numerično polje numpy.array (kar iz seznama a):

array([1, 2, 3, 4, 5, 6, 7])

Ko izpišemo b, smo opozorjeni, da gre za array([...]).

Poglejmo, kako se obnaša Pythonov seznam pri množenju:

[1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7]

Opazimo, da se podvoji seznam, ne pa vrednosti, kar bi morebiti pričakovali.

Poglejmo, kako se pri množenju obnaša numerično polje numpy.array:

array([ 2, 4, 6, 8, 10, 12, 14])

Opazimo, da se podvojijo vrednosti; tako kakor bi pričakovali, ko množimo na primer skalarno vrednost in vektor!

Aritmetične operacije

Izbor aritmetičnih operacij, ki jih numpy izvaja na nivoju posameznega elementa, je (po naraščajoči prioriteti):

  • x + y vsota,

  • x - y razlika,

  • x * y produkt,

  • x / y deljenje,

  • x // y celoštevilsko deljenje (rezultat je celo število zaokroženo navzdol),

  • x % y ostanek pri celoštevilskem deljenju,

  • x ** y vrne x na potenco y.

Primer:

array([ 3, 4, 3, 0, -5, -12, -21])

Vse aritmetične operacije so sicer navedene v dokumentaciji in namesto kratkih oblik imamo tudi dolge, npr: numpy.power(x, y) namesto x**y; primer:

array([ 1, 4, 9, 16, 25, 36, 49], dtype=int32)

Mimogrede opazimo, da je rezultat tipa int64 (integer). Ko smo ustvarili ime b, smo namreč ustvarili numerično polje z elementi tipa int64.

Matematične funkcije

numpy ponuja praktično vse potrebne matematične (in druge) operacije, navedimo jih po skupinah, kot so strukturirane v dokumentaciji:

Poglejmo primer funkcije sin⁡()\sin():

array([ 0.0000000e+00, 1.0000000e+00, 1.2246468e-16, -1.0000000e+00, -2.4492936e-16])

Poglejmo še hitrost izvajanja:

1.32 µs ± 105 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

Podatkovni tipi

numpy ima vnaprej definirane podatkovne tipe (statično). Celoten seznam možnih tipov je naveden v dokumentaciji.

Osredotočili se bomo predvsem na sledeče tipe:

  • int - celo število (fiksne širine, običajno 64 bitov; za razliko od Pythonovega int lahko prekorači obseg)

  • float - število s plavajočo vejico (dokumentacija)

  • complex - kompleksno število s plavajočo vejico

  • object - Python objekt.

Poglejmo si nekaj primerov (cela števila, število s plavajočo vejico in kompleksna števila):

array([0, 1, 2, 3, 4])
array([0., 1., 2., 3., 4.])
array([0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j])

Spreminjanje elementov numeričnega polja (numpy.array)

Podatke spreminjamo na podoben način kakor pri navadnih seznamih; v kolikor uporabljamo rezanje, moramo paziti, da so na levi in desni strani enačaja podatki iste oblike (array.shape).

Poglejmo si primer, ko matriki ničel dimenzije 3 x 4 spremenimo element z indeksom [2, 3]:

array([[ 0., 0., 0., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 100.]])

Sedaj spremenimo še elemente prvih dveh vrstic in prvih dveh stolpcev v vrednost 1:

array([[ 1., 1., 0., 0.], [ 1., 1., 0., 0.], [ 0., 0., 0., 100.]])

Z 2 pomnožimo stolpec z indeksom 1:

array([[ 1., 2., 0., 0.], [ 1., 2., 0., 0.], [ 0., 0., 0., 100.]])

Bodite pozorni na to, da na tak način naredimo pogled (view) na podatke (ne naredimo kopije podatkov).

Za primer najprej naredimo novo ime pogled:

array([0., 0., 0.])

Sedaj spremenimo izbrane vrednosti numeričnega polja a:

array([[ 1., 2., 5., 0.], [ 1., 2., 5., 0.], [ 0., 0., 5., 100.]])

Vrednosti pogled nismo spreminjali. Ker pa ime kaže na isto mesto kakor a[:, 2], so vrednosti spremenjene:

array([5., 5., 5.])

Če želimo kopijo, moramo narediti tako:

array([5., 5., 5.])

in rezultat kopija ostane nespremenjen:

array([5., 5., 5.])

Osnove matričnega računanja

Če želite ponoviti matematične osnove matričnega računanja, potem sledite tej povezavi (gre za kratek in dober pregled prof. dr. T. Koširja). Pogledali bomo, kako matrične račune izvedemo s pomočjo paketa numpy.

Najprej definirajmo matriki A\mathbf{A} in B\mathbf{B}:

ter vektorja x\mathbf{x} in y\mathbf{y}.

Skalarni produkt dveh vektorjev izvedemo s funkcijo dot() (dokumentacija):

numpy.dot(a, b, out=None)

kjer argumenta a in b predstavljata numerični polji numpy.array (poljubne dimenzije), ki jih želimo množiti. Če sta a in b dimenzije 1 se izvede skalarni produkt. Pri dimenziji 2 (matrike) se izračuna produkt matrik. Za uporabo funkcije dot() pri dimenzijah več kot 2: glejte dokumentacijo.

Poglejmo primer množenja dveh vektorjev, to lahko izvedemo tako:

11

ali tudi tako:

11

Zgoraj smo omenili, da numpy.array ne sledi dosledno matematičnemu zapisu. Če bi, bi namreč eden od vektorjev moral biti vrstični, drugi stolpični. numpy to poenostavi in zato je koda lažje berljiva in krajša.

Poglejmo sedaj množenje matrike z vektorjem (opazimo, da transponiranje x ni potrebno):

array([5, 7])

Lahko pa seveda pripravimo matematično korektno transponirano obliko vektorja (ampak vidimo, da je zapis neroden):

array([[5], [7]])

Transponiranje ima sicer tudi kratko obliko, prek atributa T, npr. za matriko A\mathbf{A}:

array([[1, 3], [2, 2]])

Poglejmo si primer množenja dveh matrik:

array([[5, 5], [7, 7]])

Od Pythona 3.5 naprej se za množenje matrik (in vektorjev) uporablja tudi operator @ (dokumentacija), ki omogoča kratek in pregleden zapis.

Zgornji primeri zapisani z operatorjem @:

11
array([5, 7])
array([[5, 5], [7, 7]])

Vektorski produkt izračunamo s funkcijo numpy.cross() (dokumentacija):

numpy.cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None)

kjer a in b definirata komponente vektorjev. Če sta podani samo dve komponenti (xx in yy), se izračuna skalarna vrednost (komponenta zz); če so podane tri komponente, je rezultat tudi vektor s tremi komponentami. Uporaba funkcije je možna tudi na večdimenzijskih numeričnih poljih in temu so namenjeni preostali argumenti (glejte dokumentacijo).

Primer vektorskega produkta ravninskih vektorjev:

array(1)

Primer vektorskega produkta prostorskih vektorjev:

array([0, 0, 1])

Nekatere funkcije knjižnice numpy

Pogledali si bomo še nekatere funkcije, ki jih bolj ali manj pogosto potrebujemo.

Enotsko matriko definiramo s funkcijo numpy.identity() (dokumentacija):

numpy.identity(n, dtype=None)

kjer argument n definira število vrstic in stolpcev kvadratne matrike. Tip dtype je privzeto float.

Primer enotske matrike:

array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])

Do diagonalnih elementov matrike dostopamo s pomočjo funkcije numpy.diagonal() (dokumentacija)

numpy.diagonal(a, offset=0, axis1=0, axis2=1)

Če je matrika dvodimenzijska, potem funkcija s privzetimi argumenti vrne diagonalno os. Če je dimenzija višja od 2, se uporabi osi axis1 in axis2, da se izloči dvodimenzijsko polje, nato pa določi diagonalo glede na elemente [i, i+offset].

Poglejmo primer izločanja diagonale:

array([1., 1., 1.])

in uporabe offset=1 za sosednjo diagonalo (najprej pripravimo nesimetirčno matriko):

array([10., 0.])

Podobno sintakso kot numpy.diagonal() ima funkcija numpy.trace(), ki izračuna vsoto (sled) diagonalnih elementov (dokumentacija):

numpy.trace(a, offset=0, axis1=0, axis2=1, 
            dtype=None, out=None)

Primer sledi diagonale:

3.0

in potem sosednje diagonale:

10.0

Pogosto nas zanimata največji ali najmanjši element nekega numeričnega polja. numpy je tukaj zelo splošen. Poglejmo si na primeru funkcije numpy.max() (dokumentacija):

numpy.max(a, axis=None, out=None)

Izpostavimo argument axis, ki pove, čez kateri indeks iščemo maksimalno vrednost. Če je axis=None se določi največja vrednost v celotnem polju.

Primer izračuna največje vrednosti celotnega polja (prej poglejmo A):

array([[ 1., 10., 0.], [ 0., 1., 0.], [ 0., 0., 1.]])
array([10., 1., 1.])

Primer izračuna največje vrednosti čez vrstice (torej po stolpcih):

array([ 1., 10., 1.])

Primer izračuna največje vrednosti čez stolpce (torej po vrsticah):

array([10., 1., 1.])

Par funkcije max() je numpy.argmax(), kateri določi indekse največje vrednosti.

Primer uporabe:

array([[ 1., 10., 0.], [ 0., 1., 0.], [ 0., 0., 1.]])
array([0, 0, 2], dtype=int64)

Linearna algebra z numpy

Pozneje bomo linearno algebro bolj podrobno spoznali in bomo sami pisali algoritme. Tukaj si poglejmo nekatere osnove, ki so vgrajene v modul numpy.

Za primer najprej definirajmo matriko in vektor:

Inverzno matriko izračunamo z uporabo funkcije numpy.linalg.inv() (dokumentacija):

numpy.linalg.inv(a)
Primer:
array([[0.33333333, 0.16666667], [0.16666667, 0.33333333]])

Sistem linearnih enačb, ki ga definirata matrika koeficientov a in vektor konstant b, rešimo s pomočjo funkcije numpy.linalg.solve() (dokumentacija):

numpy.linalg.solve(a, b)

Primer:

array([0.66666667, 0.83333333])

Enakost elementov numeričnega polja a in b (znotraj določene tolerance) preverimo s funkcijo numpy.isclose() (dokumentacija):

numpy.isclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)

Primer:

array([ True, True])

Vektorizacija algoritmov

V tem poglavju želimo izpostaviti vektorizacijo algoritmov. Glede na to kako Python in numpy delujeta se je potrebno izogibati zankam. Bistveno hitreje lahko izvajamo izračune, če jih uspemo vektorizirati; to pomeni, da izračune izvajamo na nivoju vektorjev (oz. numeričnih polj) in ne elementov.

Za primer si najprej pripravimo podatke (dva vektorja dolžine 1000)

Izračunajmo skalarni produkt vektorjev z uporabo zanke for:

332833500

Izmerimo hitrost:

730 µs ± 67.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Isti rezultat pridobimo še v vektorski obliki:

6.73 µs ± 2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Vidimo, da je vektorski način bistveno hitrejši (za še hitrejši način glejte numba v dodatku)!

Osnove modula matplotlib

V Pythonu imamo več možnosti za prikaz rezultatov v grafični obliki. Najbolj uporabni paketi so:

  • matplotlib za visoko kakovostne, visoko prilagodljive slike (relativno počasno),

  • pyqtgraph za kakovostne in prilagodljive uporabniške vmesnike (zelo hitro),

  • bokeh za interaktiven prikaz v brskalniku (relativno hitro).

Obstaja še veliko drugih; dober pregled je naredil Jake VanderPlas na konferenci PyCon 2017 (sicer avtor paketa za deklarativno vizualizacijo: Altair).

Osnovna uporaba

Najbolj razširjen in najbolj splošno uporabljen je paket matplotlib: Matplotlib

Sposobnosti paketa najbolje prikazuje galerija. Gre za zelo sofisticiran paket in tukaj si bomo na podlagi primerov pogledali nekatere osnove.

Pri uporabi vam lahko koristi plonk listek: Matplotlib cheatsheet

Tipično uvozimo matplotlib.pyplot kot plt:

Znotraj Jupyter notebooka obstajata dva načina prikaza slike (v oglatem oklepaju je magic ukaz za proženje):

  1. [%matplotlib inline] : slike so vključene v notebook (medvrstični način),

  2. [%matplotlib widget] : slike so interaktivno vključene v notebook (medvrstični interaktivni način), zahteva namestitev paketa ipympl,

  3. [%matplotlib notebook] : slike so interaktivno vključene v notebook (medvrstični interaktivni način).

Opomba: interaktivni način se v pasivni, spletni/pdf verziji te knjige ne prikaže pravilno.

Tukaj bomo najpogosteje uporabljali medvrstični način:

Kratek primer:

<Figure size 640x480 with 1 Axes>

Mimogrede, zakaj to imenujemo žvižg (oz. kvadraten žvižg)? Da dobimo odgovor, podatke predvajamo na zvočnik:

Loading...

Aktivirajmo sedaj interaktivni način (glejte tudi %matplotlib):

Loading...
Loading...

Zgornjo sliko lahko sedaj interaktivno klikamo in tudi dopolnjujemo s kodo:

Interaktivna uporaba

Pri tem predmetu bomo večkrat uporabljali interaktivnost pri delu z grafičnimi prikazi. V ta namen najprej uvozimo interact iz paketa ipywidgets:

Potem definiramo sliko kot funkcijo z argumenti amplituda, fr, faza in dušenje:

Gremo nazaj na medvrstično uporabo in kličemo funkcijo za izris slike (privzeti argumenti):

Loading...
Loading...

Če funkcijo za izris slike pošljemo v funkcijo interact, slednja poskrbi za interaktivne gumbe, s katerimi lahko spreminajmo parametre klicanja funkcije slika:

Loading...

Razpon parametov lahko tudi sami definiramo:

Loading...

Napredna uporaba

Prikaz več funkcij

Poglejmo si preprost primer prikaza več funkcij (najprej, opcijsko, definirajmo fonte za izpis v pdf):

<Figure size 640x480 with 1 Axes>
Prikaz več slik

Več slik prikažemo s pomočjo metode subplot, ki definira mrežo in lego naslednjega izrisala.

plt.subplot(2, 2, 1)
plt.plot(x, y1, 'r')
plt.subplot(2, 2, 2)
plt.plot(x, y2, 'g')

V primeru zgoraj plt.subplot(2, 2, 1) pomeni: mreža naj bo 2 x 2, riši v sliko 1 (levo zgoraj). Naslednjič se kliče plt.subplot(2, 2, 2) kar pomeni mreža 2 x 2, riši v sliko 2 (desno zgoraj) in tako naprej. Opazimo, da se indeks slik začne z 1; lahko bi rekli, da gre za nekonsistentnost v Pythonu, razlog pa je v tem, da je bil matplotlib rojen v ideji, da bi uporabnikom Pythona uporabil čimbolj podoben način izrisa, kakor so ga poznali v Matlabu (kjer se indeks začne z 1).

Delujoči primer je:

<Figure size 640x480 with 4 Axes>
Histogram

Generirajmo 10000 normalno porazdeljenih vzorcev in jih prikažimo v obliki histograma:

<Figure size 640x480 with 1 Axes>

Uporaba primerov iz matplotlib.org

Primere iz galerije lahko uvozimo s pomočjo magične funkcije %load.

Poskusite:

  • %load http://matplotlib.org/mpl_examples/lines_bars_and_markers/fill_demo.py

  • %load http://matplotlib.org/examples/widgets/slider_demo.py

Dodatno:

Numba

Paket numba se v zadnjem obdobju zelo razvija in lahko numerično izvajanje še dodatno pohitri (tudi v povezavi z grafičnimi karticami oz. GPU procesorji).

Za zgled tukaj uporabimo jit (just-in-time compilation) iz paketa numba:

jit uporabimo kot dekorator funkcije, ki jo želimo pohitriti:

Sedaj definirajmo vektorja:

Preverimo hitrost numpy skalarnega produkta:

2.44 μs ± 364 ns per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

Preverimo še hitrost numba pohitrene verzije. Prvi klic izvedemo, da se izvede kompilacija, potem merimo čas:

332833500
882 ns ± 70.8 ns per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

Vidimo, da smo še izboljšali hitrost!

matplotlib: animacije, povratni klic, XKCD stil

Z matplotlib lahko pripravimo tudi animacije. Dva primera lahko najdete tukaj:

Več v dokumentaciji.

Slika s povratnim klicem (angl. call back):

Pripravite lahko tudi na roko narisane slike (XKCD stil):

Za najbolj zagrete

  1. Naučite se še kaj novega na chrisalbon.com.


Vprašanja za vaje


Modul numpy

Vprašanje 1: Uvozite modul numpy s krajšim imenom, np.

Poljuben seznam števil pretvorite v numpy numerično polje, prikažite vpliv argumenta dtype.

Vprašanje 2: z uporabo funkcij numpy.arange in numpy.linspace pripravite numerično polje celih števil, večjih ali enakih 0 in manjših od 10.

Vprašanje 3: Z uporabo funkcije modula numpy pripravite matriko (dvodimenzionalno numerično polje) ničel, dimenzij 5×65 \times 6, in jo shranite v spremenljivko A.

Z uporabo ustreznega numpy ukaza izpišite število vrstic in število stolpcev matrike A.

Vprašanje 4: Prvi stolpec pripravljene matrike A zapolnite z vrednosti iz poljubnega numeričnega polja ustrezne dolžine.

Vprašanje 5: Iz pripravljene matrike A z rezanjem numeričnih polj pripravite kvadratno matriko B, tako, da izpustite prvi stolpec.

Vprašanje 6: V matriki A prvo vrstico zamenjajte z enicami. Izpišite matriko B in komentirajte.

Operacije nad numeričnimi polji

Vprašanje 7: Pripravite numerično polje z vrednostmi maksimalnih elementov vsake od vrstic pripravljene matrike A.

Vprašanje 8: Na pripravljenem numeričnem polju opazujte uporabo osnovnih matematičnih operacij nad numeričnimi polji (*, /, //, sin, cos, sqrt...).

Komentirajte razliko v primerjavi s seznami!

Linearna algebra z numpy

Vprašanje 9: Pripravite enotsko matriko I. Pomnožite jo s poljubnim vektorjem ustrezne dolžine.

Vprašanje 10: Izračunajte inverz matrike M in pravilnost rezultata preverite z operacijo množenja matrik.

Vprašanje 11: Z uporabo numpy orodij rešite sistem linearnih enačb Mx = b.


Modul matplotlib

Vprašanje 12: Z uporabo matplotlib.pyplot na istem grafu izrišite spodaj definiranje krivulje. Prikažite uporabo različnih tipov in barv črt.

Vprašanje 13: Na zgoraj izrisanem grafu prikažite uporabo legende, naslova in oznak koordinatnih osi, ter izrišite koordinatno mrežo.