IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

3. diel - Tvorba polí

V predchádzajúcej lekcii, Dátové typy, sme sa pozreli na to, aké základné dátové typy používa knižnica NumPy a ako sa s nimi pracuje.

V tomto tutoriále knižnice NumPy v Pythone sa pozrieme na pole v knižnici NumPy a naučíme sa ich vytvárať. Vysvetlíme si, aké je dôležité udržiavať pole homogénne.

Poľa v NumPy - ndarray

Polia, ktoré poskytuje knižnica NumPy, sa do značnej miery správajú podobne ako bežné zoznamy v Pythone. Je možné do nich ukladať najrôznejšie typy premenných - čísla, reťazce i všeobecné objekty a potom k prvkom pristupovať, prípadne ich meniť. Oproti bežným zoznamom v Pythone ale nie je možné do nich prvky pridávať a odoberať. Polia v NumPy majú pevne daný počet prvkov, podobne ako to majú polia v jazykoch C alebo Java.

Pole vs. zoznam - rozlíšenie pojmov

Ešte raz si zopakujme veľmi dôležitý poznatok, ktorý sme spomenuli v lekcii NumPy - Predstavenie knižnice v kapitole Zoznamy v Pythone vs NumPy arrays. Zoznamy v Pythone sú dynamické. Zodpovedajú tomu, čo v iných jazykoch označujeme ako list – zoznam. Oproti tomu v NumPy sa jedná o skutočné pole - array, ako ich poznáme z jazykov C či Java. V NumPy ich budeme označovať aj ich technickým názvom ako ndarray. Natívne zoznamy Pythona a poľa NumPy budeme v tutoriáli striktne odlišovať.

Ukážme si ešte pre istotu kód zoznamu a poľa:

list = [1, 2, 3]    # list
print(type(list))

array = np.array([1, 2, 3])    # ndarray
print(type(array))

Vo výstupe konzoly dostaneme:

The difference between a list and an array:
class 'list'
class 'numpy.ndarray'

Poľa vs. zoznam - kedy použiť čo?

Prečo by sme mali použiť NumPy ndarray, keď nám oproti Pythonovskému zoznamu neumožňuje pridávať a odoberať prvky? Odpovede sú dve - čas a priestor v pamäti. S poľom sa počítaču zaobchádza jednoduchšie. Akonáhle sa raz pole vytvorí v pamäti, jeho dĺžka zostáva až do zmazania Garbage Collectorom konštantná. Samozrejme sa občas nejaká hodnota v ňom zmení, ale to je všetko.

Preto ak pracujeme s veľkým množstvom hodnôt alebo operácií, je všeobecne rýchlejšie aj úspornejšie použiť ndarray. Inak samozrejme môžeme použiť aj základný Python zoznam.

Ako sa vytvára pole v NumPy

Existuje viacero spôsobov, ako ndarray vytvoriť. Najčastejšie použijeme "premenu" zoznamu pomocou metódy np.array(). NumPy však obsahuje mnoho ďalších zaujímavých funkcií a metód, ktoré poskytujú ndarray na výstupe. Pozrime sa na niektoré z nich.

Vytvorenie NumPy poľa z Python zoznamu

Najprv si ukážeme už spomínanú metódu np.array():

natural_numbers_array = np.array([1, 2, 3])
animals_array = np.array(['dog', 'cat', 'pterodactyl'])
date_array = np.array([np.datetime64('2023-07-20T17:23:10.42'), np.datetime64('2023-07-20'), np.datetime64('2023-07')])

Všeobecne je nevhodné miešať rôzne typy v jednom poli. Dátový typ NumPy poľa pri jeho vytvorení buď explicitne špecifikujeme, alebo je automaticky určený na základe hodnôt, ktoré do poľa vložíme. Pokiaľ vložíme do jedného poľa rôzne typy dát, NumPy ich všetky prevedie na jednotný typ. Vyberie pritom taký, ktorý dokáže reprezentovať všetky vložené hodnoty. Uveďme si príklad. Ak vytvoríme pole s celými číslami a jedno z nich bude desatinné, všetky čísla budú prevedené na desatinné. Podobne, ak pridáme reťazec do poľa s celými číslami, všetky čísla budú prevedené na reťazce. Je zrejmé, ako nepekne toto dokáže ovplyvniť výsledky matematických operácií.

Pretypovanie v poli je nákladné z hľadiska výkonu a ide o veľmi jednoduchý spôsob, ako si prirobiť naozaj nepríjemné problémy s neočakávaným správaním programu. Preto sa snažíme pole udržiavať homogénne.

No a ak budeme naozaj kreatívni a do jedného poľa namixujeme toľko typov, že NumPy nedokáže nájsť jeden, ktorý by ich zastrešil, vznikne nám pole prvkov object:

mixed_array = np.array([1, 'dog', np.datetime64('2023-07-20T17:23:10.42')])
print(mixed_array.dtype)

Vo výstupe uvidíme:

Type of array elements:
object

Vytváranie viacrozmerných polí

Poďme si ukázať, ako s pomocou metódy np.array() vytvoríme viacrozmerné polia:

array_2D = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
array_3D = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
Prístup k prvkom v 3D poli

Naše array_3D má formát 2 x (2 x 3). Predstavme si ho ako kinosála. Formát 2 x (2 x 3) nám hovorí, že máme prízemie a poschodie av každom z nich dva rady po troch sedadlách. Rozložme si zápis poľa tak, aby bol intuitívnejší:

array_3D = np.array([
[[1, 2, 3],    # first floor, first row
[4, 5, 6]],    # first floor, second row
[[7, 8, 9],    # second floor, first row
[10, 11, 12]]  # second floor, second row
])

# access to seat number 12 on the floor:
seat = array_3D[1, 1, 2]  # the variable seat will contain the number 12

Zaujímavosťou je, že môžeme vytvoriť aj polia s "dimenziou 0":

array_0D = np.array(10)

V podstate tým do poľa uložíme iba jednu hodnotu. Ak vytlačíme obsah premennej array_0D, dostaneme hodnotu 10. Pokiaľ však zistíme typ premennej, dostaneme ndarray, nie integer:

print(array_0D)
print(type(array_0D))

V konzole uvidíme:

Array with dimension 0:
10

	
	

Náhodné celé číslo - np.random.randint()

Metóda randint() v module random knižnice NumPy je základná funkcia pre generovanie náhodných čísel typu integer. Ako pre vygenerovanie jednej náhodnej hodnoty, tak aj celého (aj viacrozmerného) poľa náhodných hodnôt.

Funkcie a metódy v module random máme k dispozícii buď priamo z knižnice (np.random), alebo si modul pridáme priamo ako premennú. To je spôsob, aký budeme kvôli zjednodušeniu kódu používať v tutoriáli:

import numpy.random as random

Teraz už môžeme premennú random používať priamo.

Metóda randint() funguje jednoducho a poznáme ju už z kurzu Základná konštrukcia jazyka Pythonu z lekcie Knižnice math a random. Nechajme si teda vygenerovať náhodné číslo od nuly do devätnástich:

random_number = random.randint(20)

Je potrebné si uvedomiť, že ako mnoho ďalších knižníc a funkcií v Pythone, aj NumPy používa spodnú definovanú hranicu intervalu "vrátane" (inkluzívne) a hornú hranicu "bez" (exkluzívne). V našom prípade kód random.randint(20) znamená v reči matematiky interval <0; 20).

Poľa náhod :-)

Pokiaľ chceme vytvoriť pole náhodných hodnôt, vyplníme metóde argument požadovanej dĺžky poľa size:

array_random_numbers = random.randint(3, 20, size=(5)) # meaning: fill an array of length 5 with numbers from 3 to 19
print(array_random_numbers)
print()
array_2D_random_numbers = random.randint(3, 20, size=(5, 4)) # fill an array with five rows and four columns with numbers from 3 to 19
print(array_2D_random_numbers)

Výstup v konzole:

Konzolová aplikácia
[ 8  7  7  5 17]

[[19  8 14  8]
 [14  5  5  3]
 [ 4  6 17 10]
 [16 14  5  6]
 [19 18  8  9]]

Náhodný double - np.random.rand()

Metóda rand() má trochu odlišnú syntax. Táto metóda generuje náhodné číslo medzi 0 a 1. Opäť v half-open intervale, avšak tentoraz <0; 1). Pokiaľ chceme získať desatinné číslo v inom intervale, musíme funkciu rand() prenásobiť a posunúť. Povedzme, že chceme náhodné číslo v intervale <10, 30):

random_decimal_number = random.rand() * 20 + 10

Viac si o náhodných číslach povieme v ďalších lekciách. Teraz sa presunieme na vytváranie polí. NumPy ndarray pomocou metódy rand() vytvoríme tak, že do argumentu dáme číslo označujúce rozmer poľa, ktoré chceme:

# Array of random numbers of length 3
random_1D_array = random.rand(3)

Získali sme polia troch čísel z intervalu <0,1). Podobne vytvoríme aj viacrozmerné polia - jednoducho len pridáme číslo označujúce ďalší rozmer:

# Matrix of random numbers with dimensions 3×4
random_2D_array = random.rand(3, 4)

Pre čísla v inom intervale ako <0,1) opäť použijeme posunutie násobením a pripočítaním čísla.

To je pre túto lekciu všetko.

V nasledujúcom kvíze, Kvíz - Dátové typy a polia v NumPy, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Predchádzajúci článok
Dátové typy
Všetky články v sekcii
NumPy - Matematika v Pythone
Preskočiť článok
(neodporúčame)
Kvíz - Dátové typy a polia v NumPy
Článok pre vás napísal Miloš Halda
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje především bioinformatice a s ní souvisejícím tématům. Nevyhýbá se OOP jazykům, statistice a nástrojům pro analýzu dat.
Aktivity