G. Jagiella | ostatnia modyfikacja: 31.10.2025 |
Rozważmy tablicę (np. liczb):
| 2.5 | 3.6 | 1.0 | -1.0 |
| -1.0 | 10.3 | 11.3 | 1.4 |
| 1.0 | 3.4 | -6.0 | 1.2 |
Każdy wiersz możemy traktować jak ciąg wartości, natomiast całą tablicę jako ciąg wierszy.
Ciąg możemy reprezentować jako listę.
Zatem: tablicę można reprezentować jako listę list.
table = [[2.5, 3.6, 1.0, -1.0],
[-1.0, 10.3, 11.3, 1.4],
[1.0, 3.4, -6.0, 1.2]]
print(table)
[[2.5, 3.6, 1.0, -1.0], [-1.0, 10.3, 11.3, 1.4], [1.0, 3.4, -6.0, 1.2]]
table[i] to i-ta lista, czyli i-ty wiersz, a wiersz ten można indeksować:
table[1][2]
11.3
table[1][2] = 100
print(table)
[[2.5, 3.6, 1.0, -1.0], [-1.0, 10.3, 100, 1.4], [1.0, 3.4, -6.0, 1.2]]
Tablice niekoniecznie złożone z liczb:
board = [['🌊', '🌊', '🟩', '🌳'],
['🌊', '🟩', '🌳', '🌳'],
['🟩', '🏰', '🐉', '🌳'],
['🟩', '🟩', '⛰️', '⛰️']]
Dla wyższych wymiarów (np. liczby ułożone w kostkę) - listy tablic, czyli listy list list.

Taki sposób reprezentacji danych tabelarycznych jest naturalny w "czystym" Pythonie, jednak do przechowywania i obróbki takich danych służą wyspecjalizowane biblioteki. Przykład na dziś": numpy.
numpy¶!pip install numpy
import numpy as np # zwyczajowy skrót
Główne cele biblioteki:
numpy to w praktyce lingua franca dla ML.Typ ndarray: wielowymiarowa tablica obiektów (zazwyczaj liczb).
X = np.array([[1, 2, 3], [4, 5, 6]])
print(X)
print(type(X))
X[0][0] = 50
print(X)
X[0,0] = 100 # jak X[0][0]
print(X)
[[1 2 3] [4 5 6]] <class 'numpy.ndarray'> [[50 2 3] [ 4 5 6]] [[100 2 3] [ 4 5 6]]
Inne kształty:
X = np.array([[1, 2, 3], [4, 5, 6]]) # dwa wymiary
print(X.shape)
(2, 3)
X = np.array([1, 2, 3]) # jeden wymiar: ciąg
print(X.shape)
(3,)
X = np.array([[[1, 2, 3], [4, 5, 6]], [[11, 12, 13], [14, 15, 16]]])
print(X)
print(X.shape)
[[[ 1 2 3] [ 4 5 6]] [[11 12 13] [14 15 16]]] (2, 2, 3)
ndarray¶Indeksowanie i slicing:
A = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(A)
[[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]]
A[1]
array([5, 6, 7, 8])
A[1].shape
(4,)
A[1, 1]
6
A[0:2, 1:3]
array([[2, 3],
[6, 7]])
A[0:2, 1]
array([2, 6])
A[:, 1:]
array([[ 2, 3, 4],
[ 6, 7, 8],
[10, 11, 12]])
A[:2, :2] = np.array([[100, 101], [102, 103]])
print(X)
[[[ 1 2 3] [ 4 5 6]] [[11 12 13] [14 15 16]]]
A[:2, :2] = -1
print(X)
[[[ 1 2 3] [ 4 5 6]] [[11 12 13] [14 15 16]]]
X = np.array([[1, 2, 3], [4, 5, 6]])
print(X)
[[1 2 3] [4 5 6]]
np.sum(X)
21
np.mean(X)
3.5
np.max(X)
6
np.sum(X, axis=0)
array([5, 7, 9])
np.sum(X, axis=1)
array([ 6, 15])
X = np.array([[1, 2, 3], [4, 5, 6]])
Y = np.array([[7, 8, 9], [10, 11, 12]])
print(X)
print()
print(Y)
[[1 2 3] [4 5 6]] [[ 7 8 9] [10 11 12]]
print(X + Y)
[[ 8 10 12] [14 16 18]]
print(X * Y)
[[ 7 16 27] [40 55 72]]
print(X / Y)
[[0.14285714 0.25 0.33333333] [0.4 0.45454545 0.5 ]]
print(Y % X)
[[0 0 0] [2 1 0]]
print(X + 1000)
[[1001 1002 1003] [1004 1005 1006]]
print(X * 0.5)
[[0.5 1. 1.5] [2. 2.5 3. ]]
print(1 / X)
[[1. 0.5 0.33333333] [0.25 0.2 0.16666667]]
X = np.array([1, 2, 3])
Y = np.array([5, 4, 3])
np.dot(X, Y) # iloczyn skalarny
22
X = np.array([[1, 2, 3], [4, 5, 6]])
print(X)
[[1 2 3] [4 5 6]]
np.sin(X)
array([[ 0.84147098, 0.90929743, 0.14112001],
[-0.7568025 , -0.95892427, -0.2794155 ]])
np.cos(X)
array([[ 0.54030231, -0.41614684, -0.9899925 ],
[-0.65364362, 0.28366219, 0.96017029]])
np.exp(X)
array([[ 2.71828183, 7.3890561 , 20.08553692],
[ 54.59815003, 148.4131591 , 403.42879349]])
Dzięki temu można pisać całe wyrażenia i wyliczać je dla wszystkich elementów danej tablicy:
np.sin(X)**2
array([[0.70807342, 0.82682181, 0.01991486],
[0.57275002, 0.91953576, 0.07807302]])
np.sin(X)**2 + np.cos(X)**2
array([[1., 1., 1.],
[1., 1., 1.]])
np.zeros((3, 4))
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
np.ones((3, 4))
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
np.full((3, 4), 2025)
array([[2025, 2025, 2025, 2025],
[2025, 2025, 2025, 2025],
[2025, 2025, 2025, 2025]])
np.linspace(-10, 10, 25)
array([-10. , -9.16666667, -8.33333333, -7.5 ,
-6.66666667, -5.83333333, -5. , -4.16666667,
-3.33333333, -2.5 , -1.66666667, -0.83333333,
0. , 0.83333333, 1.66666667, 2.5 ,
3.33333333, 4.16666667, 5. , 5.83333333,
6.66666667, 7.5 , 8.33333333, 9.16666667,
10. ])
np.arange(0, 5, 0.1)
array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 1.1, 1.2,
1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2. , 2.1, 2.2, 2.3, 2.4, 2.5,
2.6, 2.7, 2.8, 2.9, 3. , 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8,
3.9, 4. , 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9])
matplotlib¶import matplotlib.pyplot as plt
X = np.linspace(0, 2 * np.pi, 100)
X
array([0. , 0.06346652, 0.12693304, 0.19039955, 0.25386607,
0.31733259, 0.38079911, 0.44426563, 0.50773215, 0.57119866,
0.63466518, 0.6981317 , 0.76159822, 0.82506474, 0.88853126,
0.95199777, 1.01546429, 1.07893081, 1.14239733, 1.20586385,
1.26933037, 1.33279688, 1.3962634 , 1.45972992, 1.52319644,
1.58666296, 1.65012947, 1.71359599, 1.77706251, 1.84052903,
1.90399555, 1.96746207, 2.03092858, 2.0943951 , 2.15786162,
2.22132814, 2.28479466, 2.34826118, 2.41172769, 2.47519421,
2.53866073, 2.60212725, 2.66559377, 2.72906028, 2.7925268 ,
2.85599332, 2.91945984, 2.98292636, 3.04639288, 3.10985939,
3.17332591, 3.23679243, 3.30025895, 3.36372547, 3.42719199,
3.4906585 , 3.55412502, 3.61759154, 3.68105806, 3.74452458,
3.8079911 , 3.87145761, 3.93492413, 3.99839065, 4.06185717,
4.12532369, 4.1887902 , 4.25225672, 4.31572324, 4.37918976,
4.44265628, 4.5061228 , 4.56958931, 4.63305583, 4.69652235,
4.75998887, 4.82345539, 4.88692191, 4.95038842, 5.01385494,
5.07732146, 5.14078798, 5.2042545 , 5.26772102, 5.33118753,
5.39465405, 5.45812057, 5.52158709, 5.58505361, 5.64852012,
5.71198664, 5.77545316, 5.83891968, 5.9023862 , 5.96585272,
6.02931923, 6.09278575, 6.15625227, 6.21971879, 6.28318531])
Y = np.sin(X)
plt.plot(X, Y)
plt.show()
X = np.arange(0, 10, 0.01)
plt.plot(X, 2 * X + 1)
plt.plot(X, X ** 2 / 2)
plt.plot(X, 5 * np.cos(X))
plt.show()
Tablice numpy są używane wprost w matplotlib i innych bibliotekach.
Przykład: ręcznie napisany obraz monochromatyczny jako tablica wymiaru (wiersze) $\times$ (kolumny), gdzie liczba rzeczywista z przedziału $[0, 1]$ reprezentuje natężenie.
Z = np.array([[1, 0.5, 1, 0.33, 1], [0, 1, 0.33, 0, 0], [0, 0.5, 0.5, 1, 0.25], [0.5, 1, 0.33, 0.25, 1]])
plt.imshow(Z) # wyświetla tablicę jako obraz monochromatyczny - paleta domyślna lub dostarczona przez użytkownika
plt.show()
Rysunek jest w "domyślnej" palecie. Inna paleta (w której najmniejsza wartość to [niemal] biały, największa to czerwony):
plt.imshow(Z, cmap="Reds")
plt.show()
A kolorowe obrazki?
Przypomnienie: kolor można opisać za pomocą trzech składowych (R - czerwona, G - zielona, B - niebieska). Natężenie każdej ze składowych wyraża się jako liczba ze zbioru $\{0, 1, \ldots, 255\}$.
Każdą składową można zebrać w tablicę.
R = np.array([[0, 128, 0, 255], [255, 128, 255, 0]])
G = np.array([[0, 255, 0, 255], [255, 0, 128, 255]])
B = np.array([[0, 255, 255, 0], [255, 0, 128, 128]])
_, (i1, i2, i3) = plt.subplots(1, 3) # trochę magii
i1.imshow(R, cmap="gray")
i2.imshow(G, cmap="gray")
i3.imshow(B, cmap="gray")
plt.show()
Składowe można zebrać w trójwymiarową tablicę rozmiaru (wiersze) $\times$ (kolumny) $\times$ 3.
Z = np.stack((R, G, B), axis=2)
print(Z.shape)
print(Z[:,:,0])
(2, 4, 3) [[ 0 128 0 255] [255 128 255 0]]
plt.imshow(Z) # tablica (height, width, 3)
plt.show()
To już demonstracja konkretnych narzędzi (niekoniecznie z myślą o laboratoriach):
!pip install imageio
import imageio # obsługa obrazków
cat = imageio.v2.imread("https://math.uni.wroc.pl/~jagiella/files/pwai/cat.jpg")
cat.shape
(297, 400, 3)
plt.imshow(cat)
plt.show()
plt.imshow(cat[:, :, 0], cmap="gray") # "czerwona składowa" kota
plt.show()
_, (i1, i2, i3) = plt.subplots(1, 3, figsize=(15, 15)) # trochę podobnej magii
i1.imshow(cat[:, :, 0], cmap='gray')
i2.imshow(cat[:, :, 1], cmap='gray')
i3.imshow(cat[:, :, 2], cmap='gray')
plt.show()
eyes = cat[95:125, 165:240, :]
plt.imshow(eyes)
plt.show()
cat[95:125, 165:240, 0] = 0
plt.imshow(cat)
plt.show()
cat[95:125, 165:240] = 0
plt.imshow(cat)
plt.show()
cat = imageio.v2.imread("https://math.uni.wroc.pl/~jagiella/files/pwai/cat.jpg")
cat[:, :, 2] = cat[:, :, 0]
plt.imshow(cat)
plt.show()
cat = imageio.v2.imread("https://math.uni.wroc.pl/~jagiella/files/pwai/cat.jpg")
cat[95:125, 265:340, 1:] = cat[95:125, 165:240, 0:2]
cat[95:125, 265:340, 0] = 0
plt.imshow(cat)
plt.show()
cat = imageio.v2.imread("https://math.uni.wroc.pl/~jagiella/files/pwai/cat.jpg")
plt.imshow(255 - cat)
plt.show()
plt.imshow(cat // 2)
plt.show()
plt.imshow(np.clip(cat**1.1, 0, 255).astype(np.uint8))
plt.show()