Ostatnia aktualizacja: 2022-04-02 17:09:57
NumPy
NumPy jest biblioteką Pythona służącą do obliczeń naukowych.
Zastosowania:
- algebra liniowa
- zaawansowane obliczenia matematyczne (numeryczne)
- całkowania
- rozwiązywanie równań
- …
Import biblioteki NumPy
import numpy as np
Podstawowym bytem w bibliotece NumPy jest N-wymiarowa tablica zwana
ndarray
. Każdy element na tablicy traktowany jest jako typ
dtype
.
object, dtype=None, copy=True,
numpy.array(='K', subok=False, ndmin=0) order
- object - to co ma być wrzucone do tablicy
- dtype - typ
- copy - czy obiekty mają być skopiowane, domyślne
True
- order - sposób układania: C (rzędy), F (kolumny), A, K
- subok - realizowane przez podklasy (jeśli
True
), domyślnieFalse
- ndmin - minimalny rozmiar (wymiar) tablicy
import numpy as np
= np.array([1, 2, 3])
a print(a)
= np.array([1, 2, 3.0])
b print(b)
= np.array([[1, 2], [3, 4]])
c print(c)
= np.array([1, 2, 3], ndmin=2)
d print(d)
= np.array([1, 2, 3], dtype=complex)
e print(e)
= np.array(np.mat('1 2; 3 4'))
f print(f)
= np.array(np.mat('1 2; 3 4'), subok=True)
g print(g)
## [1 2 3]
## [1. 2. 3.]
## [[1 2]
## [3 4]]
## [[1 2 3]]
## [1.+0.j 2.+0.j 3.+0.j]
## [[1 2]
## [3 4]]
## [[1 2]
## [3 4]]
Lista a tablica
import numpy as np
import time
= time.time()
start_time = np.arange(1000000)
my_arr = list(range(1000000))
my_list = time.time()
start_time = my_arr * 2
my_arr2 print("--- %s seconds ---" % (time.time() - start_time))
= time.time()
start_time = [x * 2 for x in my_list]
my_list2 print("--- %s seconds ---" % (time.time() - start_time))
## --- 0.0158383846282959 seconds ---
## --- 0.08654999732971191 seconds ---
Atrybuty tablic ndarray
Atrybut | Opis |
---|---|
shape |
krotka z informacją liczbę elementów dla każdego z wymiarów |
size |
liczba elementów w tablicy (łączna) |
ndim |
liczba wymiarów tablicy |
nbytes |
liczba bajtów jaką tablica zajmuje w pamięci |
dtype |
typ danych |
https://numpy.org/doc/stable/reference/arrays.ndarray.html#array-attributes
import numpy as np
= np.array([2, -3, 4, -8, 1])
tab1 print(type(tab1))
print(tab1.shape)
print(tab1.size)
print(tab1.ndim)
print(tab1.nbytes)
print(tab1.dtype)
## <class 'numpy.ndarray'>
## (5,)
## 5
## 1
## 20
## int32
import numpy as np
= np.array([[2, -3], [4, -8]])
tab2 print(type(tab2))
print(tab2.shape)
print(tab2.size)
print(tab2.ndim)
print(tab2.nbytes)
print(tab2.dtype)
= np.array([[2, -3], [4, -8, 5], [3]])
tab3 print(type(tab3))
print(tab3.shape)
print(tab3.size)
print(tab3.ndim)
print(tab3.nbytes)
print(tab3.dtype)
## <class 'numpy.ndarray'>
## (2, 2)
## 4
## 2
## 16
## int32
## <string>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
## <class 'numpy.ndarray'>
## (3,)
## 3
## 1
## 24
## object
Typy danych
https://numpy.org/doc/stable/reference/arrays.scalars.html
https://numpy.org/doc/stable/reference/arrays.dtypes.html#arrays-dtypes-constructing
Typy całkowitoliczbowe | int ,int8 ,int16 ,int32 ,int64 |
Typy całkowitoliczbowe (bez znaku) | uint ,uint8 ,uint16 ,uint32 ,uint64 |
Typ logiczny | bool |
Typy zmiennoprzecinkowe | float , float16 , float32 ,
float64 , float128 |
Typy zmiennoprzecinkowe zespolone | complex , complex64 ,
complex128 , complex256 |
Napis | str |
import numpy as np
= np.array([[2, -3], [4, -8]])
tab print(tab)
= np.array([[2, -3], [4, -8]], dtype=int)
tab2 print(tab2)
= np.array([[2, -3], [4, -8]], dtype=float)
tab3 print(tab3)
= np.array([[2, -3], [4, -8]], dtype=complex)
tab4 print(tab4)
## [[ 2 -3]
## [ 4 -8]]
## [[ 2 -3]
## [ 4 -8]]
## [[ 2. -3.]
## [ 4. -8.]]
## [[ 2.+0.j -3.+0.j]
## [ 4.+0.j -8.+0.j]]
Tworzenie tablic
np.array
- argumenty rzutowany na tablicę (coś po czym
można iterować) - warto sprawdzić rozmiar/kształt
import numpy as np
= np.array([2, -3, 4])
tab print(tab)
= np.array((4, -3, 3, 2))
tab2 print(tab2)
= np.array({3, 3, 2, 5, 2})
tab3 print(tab3)
= np.array({"pl": 344, "en": 22})
tab4 print(tab4)
## [ 2 -3 4]
## [ 4 -3 3 2]
## {2, 3, 5}
## {'pl': 344, 'en': 22}
np.zeros
- tworzy tablicę wypełnioną zerami
import numpy as np
= np.zeros(4)
tab print(tab)
print(tab.shape)
= np.zeros([2, 3])
tab2 print(tab2)
print(tab2.shape)
= np.zeros([2, 3, 4])
tab3 print(tab3)
print(tab3.shape)
## [0. 0. 0. 0.]
## (4,)
## [[0. 0. 0.]
## [0. 0. 0.]]
## (2, 3)
## [[[0. 0. 0. 0.]
## [0. 0. 0. 0.]
## [0. 0. 0. 0.]]
##
## [[0. 0. 0. 0.]
## [0. 0. 0. 0.]
## [0. 0. 0. 0.]]]
## (2, 3, 4)
np.ones
- tworzy tablicę wypełnioną jedynkami (to nie
odpowiednik macierzy jednostkowej!)
import numpy as np
= np.ones(4)
tab print(tab)
print(tab.shape)
= np.ones([2, 3])
tab2 print(tab2)
print(tab2.shape)
= np.ones([2, 3, 4])
tab3 print(tab3)
print(tab3.shape)
## [1. 1. 1. 1.]
## (4,)
## [[1. 1. 1.]
## [1. 1. 1.]]
## (2, 3)
## [[[1. 1. 1. 1.]
## [1. 1. 1. 1.]
## [1. 1. 1. 1.]]
##
## [[1. 1. 1. 1.]
## [1. 1. 1. 1.]
## [1. 1. 1. 1.]]]
## (2, 3, 4)
np.diag
- tworzy tablicę odpowiadającą macierzy
diagonalnej
import numpy as np
= np.diag([3, 4, 5])
tab0 print(tab0)
= np.array([[2, 3, 4], [3, -4, 5], [3, 4, -5]])
tab1 print(tab1)
= np.diag(tab1)
tab2 print(tab2)
= np.diag(tab1, k=1)
tab3 print(tab3)
= np.diag(tab1, k=-2)
tab4 print(tab4)
= np.diag(np.diag(tab1))
tab5 print(tab5)
## [[3 0 0]
## [0 4 0]
## [0 0 5]]
## [[ 2 3 4]
## [ 3 -4 5]
## [ 3 4 -5]]
## [ 2 -4 -5]
## [3 5]
## [3]
## [[ 2 0 0]
## [ 0 -4 0]
## [ 0 0 -5]]
np.arange
- tablica wypełniona równomiernymi
wartościami
Składnia:
numpy.arange([start, ]stop, [step, ]dtype=None)
import numpy as np
= np.arange(3)
a print(a)
= np.arange(3.0)
b print(b)
= np.arange(3, 7)
c print(c)
= np.arange(3, 11, 2)
d print(d)
= np.arange(0, 1, 0.1)
e print(e)
= np.arange(3, 11, 2, dtype=float)
f print(f)
= np.arange(3, 10, 2)
g print(g)
## [0 1 2]
## [0. 1. 2.]
## [3 4 5 6]
## [3 5 7 9]
## [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
## [3. 5. 7. 9.]
## [3 5 7 9]
np.linspace
- tablica wypełniona równomiernymi
wartościami wg skali liniowej
import numpy as np
= np.linspace(2.0, 3.0, num=5)
a print(a)
= np.linspace(2.0, 3.0, num=5, endpoint=False)
b print(b)
= np.linspace(2.0, 3.0, num=5, retstep=True)
c print(c)
## [2. 2.25 2.5 2.75 3. ]
## [2. 2.2 2.4 2.6 2.8]
## (array([2. , 2.25, 2.5 , 2.75, 3. ]), 0.25)
np.logspace
- tablica wypełniona wartościami wg skali
logarytmicznej
Składnia:
numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0)
import numpy as np
= np.logspace(2.0, 3.0, num=4)
a print(a)
= np.logspace(2.0, 3.0, num=4, endpoint=False)
b print(b)
= np.logspace(2.0, 3.0, num=4, base=2.0)
c print(c)
## [ 100. 215.443469 464.15888336 1000. ]
## [100. 177.827941 316.22776602 562.34132519]
## [4. 5.0396842 6.34960421 8. ]
np.empty
- pusta (niezaincjowana) tablica
import numpy as np
= np.empty(3)
a print(a)
= np.empty(3, dtype=int)
b print(b)
## [0. 1. 2.]
## [0 1 2]
np.identity
- tablica przypominająca macierz
jednostkową
np.eye
- tablica z jedynkami na przekątnej (pozostałe
zera)
import numpy as np
= np.identity(4)
a print(a)
= np.eye(4, k=1)
b print(b)
= np.eye(4, k=2)
c print(c)
= np.eye(4, k=-1)
d print(d)
## [[1. 0. 0. 0.]
## [0. 1. 0. 0.]
## [0. 0. 1. 0.]
## [0. 0. 0. 1.]]
## [[0. 1. 0. 0.]
## [0. 0. 1. 0.]
## [0. 0. 0. 1.]
## [0. 0. 0. 0.]]
## [[0. 0. 1. 0.]
## [0. 0. 0. 1.]
## [0. 0. 0. 0.]
## [0. 0. 0. 0.]]
## [[0. 0. 0. 0.]
## [1. 0. 0. 0.]
## [0. 1. 0. 0.]
## [0. 0. 1. 0.]]
Indeksowanie, “krojenie”
import numpy as np
= np.array([2, 5, -2, 4, -7, 8, 9, 11, -23, -4, -7, 8, 1])
a print(a[5])
print(a[-2])
print(a[3:6])
print(a[:])
print(a[0:-1])
print(a[:5])
print(a[4:])
print(a[4:-1])
print(a[4:10:2])
print(a[::-1])
print(a[::2])
print(a[::-2])
## 8
## 8
## [ 4 -7 8]
## [ 2 5 -2 4 -7 8 9 11 -23 -4 -7 8 1]
## [ 2 5 -2 4 -7 8 9 11 -23 -4 -7 8]
## [ 2 5 -2 4 -7]
## [ -7 8 9 11 -23 -4 -7 8 1]
## [ -7 8 9 11 -23 -4 -7 8]
## [ -7 9 -23]
## [ 1 8 -7 -4 -23 11 9 8 -7 4 -2 5 2]
## [ 2 -2 -7 9 -23 -7 1]
## [ 1 -7 -23 9 -7 -2 2]
import numpy as np
= np.array([[3, 4, 5], [-3, 4, 8], [3, 2, 9]])
a = a[:2, 1:]
b print(b)
print(np.shape(b))
= a[1]
c print(c)
print(np.shape(c))
= a[1, :]
d print(d)
print(np.shape(d))
= a[1:2, :]
e print(e)
print(np.shape(e))
= a[:, :2]
f print(f)
print(np.shape(f))
= a[1, :2]
g print(g)
print(np.shape(g))
= a[1:2, :2]
h print(h)
print(np.shape(h))
## [[4 5]
## [4 8]]
## (2, 2)
## [-3 4 8]
## (3,)
## [-3 4 8]
## (3,)
## [[-3 4 8]]
## (1, 3)
## [[ 3 4]
## [-3 4]
## [ 3 2]]
## (3, 2)
## [-3 4]
## (2,)
## [[-3 4]]
## (1, 2)
**Uwaga - takie “krojenie” to tzw “widok”.
import numpy as np
= np.array([[3, 4, 5], [-3, 4, 8], [3, 2, 9]])
a = a[1:2, 1:]
b print(b)
1][1] = 9
a[print(a)
print(b)
0][0] = -11
b[print(a)
print(b)
## [[4 8]]
## [[ 3 4 5]
## [-3 9 8]
## [ 3 2 9]]
## [[9 8]]
## [[ 3 4 5]
## [ -3 -11 8]
## [ 3 2 9]]
## [[-11 8]]
Naprawa:
import numpy as np
= np.array([[3, 4, 5], [-3, 4, 8], [3, 2, 9]])
a = a[1:2, 1:].copy()
b print(b)
1][1] = 9
a[print(a)
print(b)
0][0] = -11
b[print(a)
print(b)
## [[4 8]]
## [[ 3 4 5]
## [-3 9 8]
## [ 3 2 9]]
## [[4 8]]
## [[ 3 4 5]
## [-3 9 8]
## [ 3 2 9]]
## [[-11 8]]
Indeksowanie logiczne (fancy indexing)
import numpy as np
= np.array([2, 5, -2, 4, -7, 8, 9, 11, -23, -4, -7, 8, 1])
a = a[np.array([1, 3, 7])]
b print(b)
= a[[1, 3, 7]]
c print(c)
## [ 5 4 11]
## [ 5 4 11]
import numpy as np
= np.array([2, 5, -2, 4, -7, 8, 9, 11, -23, -4, -7, 8, 1])
a = a > 0
b print(b)
= a[a > 0]
c print(c)
## [ True True False True False True True True False False False True
## True]
## [ 2 5 4 8 9 11 8 1]
import numpy as np
= np.array([2, 5, -2, 4, -7, 8, 9, 11, -23, -4, -7, 8, 1])
a = a[a > 0]
b print(b)
0] = -5
b[print(a)
print(b)
1] = 20
a[print(a)
print(b)
## [ 2 5 4 8 9 11 8 1]
## [ 2 5 -2 4 -7 8 9 11 -23 -4 -7 8 1]
## [-5 5 4 8 9 11 8 1]
## [ 2 20 -2 4 -7 8 9 11 -23 -4 -7 8 1]
## [-5 5 4 8 9 11 8 1]
Modyfikacja kształtu i rozmiaru
https://numpy.org/doc/stable/reference/routines.array-manipulation.html
import numpy as np
= np.array([[3, 4, 5], [-3, 4, 8], [3, 2, 9]])
a = np.reshape(a, (1, 9))
b print(b)
= a.reshape(9)
c print(c)
= a.flatten()
d print(d)
= a.ravel()
e print(e)
= np.ravel(a)
f print(f)
= [[1, 3, 4]]
g = np.squeeze(g)
h print(h)
= a.T
i print(i)
= np.transpose(a)
j print(j)
= np.hstack((h, h, h))
k print(k)
= np.vstack((h, h, h))
l print(l)
= np.dstack((h, h, h))
m print(m)
## [[ 3 4 5 -3 4 8 3 2 9]]
## [ 3 4 5 -3 4 8 3 2 9]
## [ 3 4 5 -3 4 8 3 2 9]
## [ 3 4 5 -3 4 8 3 2 9]
## [ 3 4 5 -3 4 8 3 2 9]
## [1 3 4]
## [[ 3 -3 3]
## [ 4 4 2]
## [ 5 8 9]]
## [[ 3 -3 3]
## [ 4 4 2]
## [ 5 8 9]]
## [1 3 4 1 3 4 1 3 4]
## [[1 3 4]
## [1 3 4]
## [1 3 4]]
## [[[1 1 1]
## [3 3 3]
## [4 4 4]]]
import numpy as np
= np.array([[1, 2], [3, 4]])
a = np.array([[5, 6]])
b = np.concatenate((a, b))
r1 print(r1)
= np.concatenate((a, b), axis=0)
r2 print(r2)
= np.concatenate((a, b.T), axis=1)
r3 print(r3)
= np.concatenate((a, b), axis=None)
r4 print(r4)
## [[1 2]
## [3 4]
## [5 6]]
## [[1 2]
## [3 4]
## [5 6]]
## [[1 2 5]
## [3 4 6]]
## [1 2 3 4 5 6]
import numpy as np
= np.array([[1, 2], [3, 4]])
a = np.resize(a, (2, 3))
r1 print(r1)
= np.resize(a, (1, 4))
r2 print(r2)
= np.resize(a, (2, 4))
r3 print(r3)
## [[1 2 3]
## [4 1 2]]
## [[1 2 3 4]]
## [[1 2 3 4]
## [1 2 3 4]]
import numpy as np
= np.array([[1, 2], [3, 4]])
a = np.array([[5, 6]])
b = np.append(a, b)
r1 print(r1)
= np.append(a, b, axis=0)
r2 print(r2)
## [1 2 3 4 5 6]
## [[1 2]
## [3 4]
## [5 6]]
import numpy as np
= np.array([[1, 2], [3, 7]])
a = np.insert(a, 1, 4)
r1 print(r1)
= np.insert(a, 2, 4)
r2 print(r2)
= np.insert(a, 1, 4, axis=0)
r3 print(r3)
= np.insert(a, 1, 4, axis=1)
r4 print(r4)
## [1 4 2 3 7]
## [1 2 4 3 7]
## [[1 2]
## [4 4]
## [3 7]]
## [[1 4 2]
## [3 4 7]]
import numpy as np
= np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
a = np.delete(a, 1, axis=1)
r1 print(r1)
= np.delete(a, 2, axis=0)
r2 print(r2)
## [[ 1 3 4]
## [ 5 7 8]
## [ 9 11 12]]
## [[1 2 3 4]
## [5 6 7 8]]
Broadcasting
Wariant 1 - skalar-tablica - wykonanie operacji na każdym elemencie tablicy
import numpy as np
= np.array([[1, 2], [5, 6], [9, 10]])
a = a + 4
b print(b)
= 2 ** a
c print(c)
## [[ 5 6]
## [ 9 10]
## [13 14]]
## [[ 2 4]
## [ 32 64]
## [ 512 1024]]
Wariant 2 - dwie tablice - “gdy jedna z tablic może być rozszerzona” (oba wymiary są równe lub jeden z nich jest równy 1)
https://numpy.org/doc/stable/user/basics.broadcasting.html
import numpy as np
= np.array([[1, 2], [5, 6]])
a = np.array([9, 2])
b = a + b
r1 print(r1)
= a / b
r2 print(r2)
= np.array([[4], [-2]])
c = a + c
r3 print(r3)
= c / a
r4 print(r4)
## [[10 4]
## [14 8]]
## [[0.11111111 1. ]
## [0.55555556 3. ]]
## [[5 6]
## [3 4]]
## [[ 4. 2. ]
## [-0.4 -0.33333333]]
Funkcje uniwersalne
Statystyka i agregacja
Funkcja | Opis |
---|---|
np.mean | Średnia wszystkich wartości w tablicy. |
np.std | Odchylenie standardowe. |
np.var | Wariancja. |
np.sum | Suma wszystkich elementów. |
np.prod | Iloczyn wszystkich elementów. |
np.cumsum | Skumulowana suma wszystkich elementów. |
np.cumprod | Skumulowany iloczyn wszystkich elementów. |
np.min,np.max | Minimalna/maksymalna wartość w tablicy. |
np.argmin, np.argmax | Indeks minimalnej/maksymalnej wartości w tablicy. |
np.all | Sprawdza czy wszystki elementy są różne od zera. |
np.any | Sprawdza czy co najmniej jeden z elementów jest różny od zera. |
Wyrażenia warunkowe
https://numpy.org/doc/stable/reference/generated/numpy.where https://numpy.org/doc/stable/reference/generated/numpy.choose https://numpy.org/doc/stable/reference/generated/numpy.select https://numpy.org/doc/stable/reference/generated/numpy.nonzero
Działania na zbiorach
Operacje tablicowe
https://numpy.org/doc/stable/reference/generated/numpy.transpose
https://numpy.org/doc/stable/reference/generated/numpy.flip https://numpy.org/doc/stable/reference/generated/numpy.fliplr https://numpy.org/doc/stable/reference/generated/numpy.flipud
Alegbra liniowa
Funkcja na stringach
Data i czas
https://numpy.org/doc/stable/reference/arrays.datetime.html
Bibliografia:
- Dokumentacja biblioteki, https://numpy.org/doc/stable/, dostęp online 5.03.2021.
- Robert Jahansson, Matematyczny Python. Obliczenia naukowe i analiza danych z użyciem NumPy, SciPy i Matplotlib, Wyd. Helion, 2021.
- https://www.tutorialspoint.com/numpy/index.htm, dostęp online 20.03.2019.