NumPy – ćwiczenia


Ćwiczenia z NumPy

Podstawy NumPy z oficjalnej dokumentacji projektu: podstawy

Co trzeba wiedzieć

  1. Jak stworzyć tablicę (1D/2D/3D):

    1. wypełnioną zerami, jedynkami
    2. wypełnioną danymi podanymi jako lista pythona

  2. Jak zaindeksować pojedynczy element tablicy (indeksy: najpierw nr wiersza potem nr kolumny).

  3. Jak odwoływać się do zakresów: tablica[start_włącznie:koniec_bez:krok]

  4. Jak odwoływać się do wybranych elementów: tablica[boolowska_tablica] (np. spełniających kreślony warunek: tablica[tablica < 10])

  5. Odwołanie się do fragmentu (lub całości) jakiejś tablicy nie powoduje utworzenia kopii danych! Czyli modyfikując wycięty fragment tablicy modyfikujemy wybrane elementy oryginalnej tablicy.

  6. Standardowe operacje jak dodawanie i mnożenie(!) na argumentach będących tablicami wykonuje operacje na odpowiadających sobie elementach. Podobnie – funkcje takie jak np.sin obliczają swoją wartość dla każdego elementu podanej tablicy.
    Uwaga! W szczególności mnożenie (*) nie jest mnożeniem macierzowym!

  7. Funkcje takie jak np.sum czy np.max wyliczają wartość z całej tablicy.

  8. tablica.shape — wymiary tablicy
    tablica.dtype — typ elementów w tablicy

Tworzenie i interpretacja obrazów kolorowych

Obraz to tablica albo 2D (odcienie szarości – jeden piksel opisany przez jedną liczbę) albo 3D (kolorowy – jeden piksel opisany przez kilka liczb).
W przypadku obrazów kolorowych zazwyczaj korzysta się z przestrzeni barw RGB czyli jeden punkt opisuje się trzema liczbami (obraz ma 3 kanały):
- nasyceniem koloru czerwonego (Red)
- nasyceniem koloru zielonego (Green)
- nasyceniem koloru niebieskiego (Blue)

Tablice reprezentujące obrazy można tworzyć następująco:

1
2
3
4
5
#                    kolumna 0    kolumna 1    kolumna 2  ...         
image = np.array([[wartosc_0_0, wartosc_0_1, wartosc_0_2, ...],  # wiersz o indeksie 0
                  [wartosc_1_0, wartosc_1_1, wartosc_1_2, ...],  # wiersz o indeksie 1
                  ...                                            # ...
                  ])

W przypadku obrazów:

  • w odcieniach szarości (jednokanałowych): wartosc_Y_X to pojedyncza liczba,
  • kolorowych RGB (obraz z 3 kanałami): wartosc_Y_X to trójka liczb, np. [255,255,255] dla piksela białego.

Przykład – obraz w odcieniach szarości

1
2
3
4
5
image_gray = np.array([[  0, 50,100],
                       [150,200,250]], np.uint8)
                       
# czarny obraz (wypełniony zerami) o tych samych wymiarach (2 wiersza, 3 kolumny):
# czarny = np.zeros((2,3), np.uint8)
img2x3_gray.png

Przykład – obraz kolorowy RGB

1
2
3
4
5
image_rgb = np.array([[[255,  0,  0], [  0,255,  0], [  0,  0,255]],
                      [[255,255,  0], [  0,255,255], [255,  0,255]]], np.uint8)
 
# czarny obraz (wypełniony zerami) o tych samych wymiarach (2 wiersza, 3 kolumny + 3 kanały RGB):
# czarny_rgb = np.zeros((2,3,3), np.uint8)
img2x3_rgb.png

Przykład użycia

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import numpy as np
 
# tworzenie tablicy wypelnionej zerami
img = np.zeros((3,5)) # 3 wiersze, 5 kolumn
print(img)
 
# tworzenie tablicy wypelnionej kolejnymi liczbami
img = np.arange(10)
print(img)
 
# fragment tablicy - przypadek 1D
print(img[1:9])
print(img[0:10:2])
 
# tworzenie tablicy 2D wypelnionej kolejnymi liczbami
img = np.arange(15).reshape((3,5))
print(img)
print(img.shape) # wymiary tablicy
 
# fragment tablicy - przypadek 2D
print(img[1,3])
print(img[1:3])
print(img[1:3,:])
print(img[1:3,2])
print(img[1:3,::2])
 
# prosta arytmetyka
a = np.arange(5)
b = a * 2
print(a, b)
 
c = a + b
print(c)
print(a + b - c)
 
# kopiowanie
a = np.arange(5)
b = a
c = a.copy()
print(a,b,c)
b[2] = 8
print(a,b,c)

Do graficznego wizualizowania można użyć np. biblioteki matplotlib. Polecam użycie funkcji zdefiniowanej poniżej aby wyłączyć interpolację kolorów i widzieć każdy punkt obrazu z osobna.

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
import matplotlib.pyplot as plt
 
# funkcja pomocnicza ktora m.in. wylacza interpolacje
def show(image, cmap='gray', interpolation='nearest', **kwargs):
    plt.imshow(image, cmap, interpolation=interpolation, **kwargs)
    plt.show() # wyswietla okno z wykresem i czeka na jego zamkniecie
 
img = np.arange(12).reshape((3,4))
show(img)
 
img *= img
show(img)

Zadania

Proszę nie używać pętli (czyli instrukcji for, while, itp.)

  1. Napisz funkcję przyjmującą jeden argument – tablicę 2D. Funkcja ma zwracać tablicę zawierającą tylko co drugą kolumnę (o nieparzystych indeksach) z oryginalnej tablicy. Przypominam, że pierwsza kolumna ma indeks równy 0.
  2. Napisz funkcję przyjmującą jeden argument – tablicę 2D. Funkcja ma zwracać tablicę z kolumnami w odwrotnej kolejności (czyli kolumna która była pierwsza ma być w wyniku ostatnia).
  3. Napisz funkcję przyjmującą 5 parametrów: 2D tablicę liczb, współrzędne lewego górnego narożnika prostokąta (x i y) oraz jego szerokość i wysokość. Funkcja ma zwrócić sumę wszystkich liczb znajdujących się wewnątrz zadanego prostokąta. Przez współrzędną x rozumiemy kolumnę, a y — wiersz. Zakładamy, że prostokąt w całości zawiera się wewnątrz tablicy.
  4. Napisz funkcję przyjmującą 2 argumenty: tablicę liczb oraz liczbę k. Funkcja ma zwracać sumę wszystkich liczb podniesionych do potęgi k-tej.
  5. Napisz funkcję przyjmującą 2 argumenty: dwie tablice 2D a, b o identycznych wymiarach. Funkcja ma zwracać tablicę z o tych samych wymiarach, gdzie zi,j = ai,j * bi,j.
  6. Napisz funkcje przyjmującą 2 parametry: tablicę liczb oraz wartość x. Funkcja ma zwrócić sumę wszystkich liczb mniejszych niż x.
  7. Napisz funkcję przyjmującą 2 parametry: tablicę 2D oraz nieujemną liczbę całkowitą k. Funkcja ma zwrócić nową, większą tablicę powstałą poprzez dodanie “marginesu” o szerokości k z każdej strony oryginalnej tablicy (czyli szerokość/wysokość zwracanej tablicy to stara szerokość/wysokość powiększona o 2*k). Dodane elementy mają mieć wartość zero.
  8. Napisz funkcję przyjmującą jedną tablicę x. Funkcja ma zwrócić tablicę y (mającą jeden wiersz mniej niż ma x), gdzie yi,j = xi+1,j – xi,j.
  9. Napisz funkcję zwracającą tablicę 3D typu uint8 (zdefiniowany w bibliotece numpy) reprezentującą obraz kolorowy z 3 pionowymi pasami: czerwonym, zielonym i niebieskim. Szerokość pasów to np. 10 punktów, a wysokość obrazka to 30 punktów (czyli funkcja zwróci obrazek 30×30). Wartość 255 (dla typu uint8) oznacza największe nasycenie daną składową koloru.