NumPy - NumPy

NumPy
Logo NumPy 2020.svg
Pierwotny autor (autorzy) Travis Oliphant
Deweloper(zy) Projekt społeczności
Pierwsze wydanie Jak Numeryczny, 1995 ; jako NumPy, 2006 ( 1995 ) ( 2006 )
Wersja stabilna
1.21.1 / 18 lipca 2021 r .; 36 dni temu ( 18.07.2021 )
Magazyn Edytuj to na Wikidata
Napisane w Python , C
System operacyjny Wieloplatformowy
Rodzaj Analiza numeryczna
Licencja BSD
Strona internetowa numpy .org Edytuj to na Wikidanych

NumPy (wym / n ʌ m P / ( NUM -py ) lub czasami / n ʌ m P I / ( NUM -pee )) jest biblioteka na języku Python , dodanie obsługi dużych wielowymiarowych tablic i macierze wraz z dużym zbiorem funkcji matematycznych wysokiego poziomu do działania na tych tablicach. Przodek NumPy, Numeric, został pierwotnie stworzony przez Jima Hugunina przy udziale kilku innych programistów. W 2005 roku Travis Oliphant stworzył NumPy poprzez włączenie funkcji konkurencyjnego Numarray do Numeric, z rozległymi modyfikacjami. NumPy jest oprogramowaniem typu open source i ma wielu współpracowników.

Historia

Język programowania Python nie był pierwotnie przeznaczony do obliczeń numerycznych, ale wcześnie przyciągnął uwagę społeczności naukowej i inżynierskiej. W 1995 r. utworzono specjalną grupę zainteresowań (SIG) matrix-sig w celu zdefiniowania pakietu obliczeniowego macierzowego ; wśród jej członków był projektant i opiekun Pythona Guido van Rossum , który rozszerzył składnię Pythona (w szczególności składnię indeksowania), aby ułatwić przetwarzanie tablicowe .

Implementacja pakietu macierzy została ukończona przez Jima Fultona, a następnie uogólniona przez Jima Hugunina i nazwana Numeric (znana również jako „numeryczne rozszerzenia Pythona” lub „NumPy”). Hugunin, absolwent Massachusetts Institute of Technology (MIT), dołączył do Corporation for National Research Initiatives (CNRI) w 1997 roku, aby pracować nad JPythonem , pozostawiając Paula Dubois z Lawrence Livermore National Laboratory (LLNL), który przejął funkcję opiekuna. Inni wcześni współpracownicy to David Ascher, Konrad Hinsen i Travis Oliphant .

Nowy pakiet o nazwie Numarray został napisany jako bardziej elastyczny zamiennik dla Numeric. Podobnie jak Numeric, również jest teraz przestarzały. Numarray miał szybsze operacje na dużych tablicach, ale był wolniejszy niż Numeric na małych, więc przez pewien czas oba pakiety były używane równolegle w różnych przypadkach użycia. Ostatnia wersja Numeric (v24.2) została wydana 11 listopada 2005, natomiast ostatnia wersja numarray (v1.5.2) została wydana 24 sierpnia 2006.

Chciano wprowadzić Numeric do standardowej biblioteki Pythona, ale Guido van Rossum zdecydował, że kod nie był wtedy możliwy do utrzymania w jego stanie.

Na początku 2005 roku programista NumPy, Travis Oliphant, chciał zjednoczyć społeczność wokół jednego pakietu macierzy i przeniósł funkcje Numarray do Numeric, wydając wynik jako NumPy 1.0 w 2006 roku. Ten nowy projekt był częścią SciPy . Aby uniknąć instalowania dużego pakietu SciPy tylko po to, aby uzyskać obiekt tablicy, ten nowy pakiet został oddzielony i nazwany NumPy. Wsparcie dla Pythona 3 zostało dodane w 2011 z NumPy w wersji 1.5.0.

W 2011 roku PyPy rozpoczęło prace rozwojowe nad wdrożeniem NumPy API dla PyPy. Nie jest jeszcze w pełni kompatybilny z NumPy.

Cechy

NumPy jest przeznaczony dla referencyjnej implementacji Pythona CPython , która jest nieoptymalizującym interpreterem kodu bajtowego . Algorytmy matematyczne napisane dla tej wersji Pythona często działają znacznie wolniej niż skompilowane odpowiedniki. NumPy rozwiązuje problem powolności częściowo poprzez dostarczanie wielowymiarowych tablic i funkcji oraz operatorów, które działają wydajnie na tablicach; użycie ich wymaga przepisania kodu, głównie wewnętrznych pętli , za pomocą NumPy.

Używanie NumPy w Pythonie daje funkcjonalność porównywalną do MATLAB, ponieważ oba są interpretowane i oba pozwalają użytkownikowi pisać szybkie programy, o ile większość operacji działa na tablicach lub macierzach zamiast skalarów . Dla porównania, MATLAB może pochwalić się dużą liczbą dodatkowych zestawów narzędzi, w szczególności Simulink , podczas gdy NumPy jest wewnętrznie zintegrowany z Pythonem, bardziej nowoczesnym i kompletnym językiem programowania . Ponadto dostępne są komplementarne pakiety Pythona; SciPy to biblioteka, która dodaje więcej funkcji podobnych do MATLAB, a Matplotlib to pakiet do drukowania , który zapewnia funkcjonalność podobną do MATLAB. Wewnętrznie zarówno MATLAB, jak i NumPy polegają na BLAS i LAPACK do wydajnych obliczeń algebry liniowej .

Wiązania Pythona szeroko używanej biblioteki wizyjnej OpenCV wykorzystują tablice NumPy do przechowywania i operowania na danych. Ponieważ obrazy z wieloma kanałami są po prostu reprezentowane jako trójwymiarowe tablice, indeksowanie, krojenie lub maskowanie za pomocą innych tablic są bardzo wydajnymi sposobami uzyskiwania dostępu do określonych pikseli obrazu. Tablica NumPy jako uniwersalna struktura danych w OpenCV dla obrazów, wyodrębnionych punktów cech , jąder filtrów i wielu innych znacznie upraszcza przepływ pracy programistycznej i debugowanie .

Struktura danych ndarray

Podstawową funkcjonalnością NumPy jest jego "ndarray", dla n- wymiarowej tablicy, struktura danych. Te tablice są krokowymi widokami pamięci. W przeciwieństwie do wbudowanej struktury danych listowej Pythona, te tablice są jednorodnie typowane: wszystkie elementy pojedynczej tablicy muszą być tego samego typu.

Takie tablice mogą być również widokami do buforów pamięci przydzielonych przez rozszerzenia C / C++ , Cython i Fortran do interpretera CPython bez konieczności kopiowania danych, co zapewnia pewien stopień zgodności z istniejącymi bibliotekami numerycznymi. Funkcjonalność ta jest wykorzystywana przez pakiet SciPy, który zawiera wiele takich bibliotek (zwłaszcza BLAS i LAPACK). NumPy ma wbudowaną obsługę ndarray mapowanych w pamięci.

Ograniczenia

Wstawianie lub dołączanie wpisów do tablicy nie jest tak trywialnie możliwe, jak w przypadku list Pythona. Procedura np.pad(...)rozszerzania tablic faktycznie tworzy nowe tablice o pożądanym kształcie i wartościach wypełnienia, kopiuje daną tablicę do nowej i zwraca ją. np.concatenate([a1,a2])Operacja NumPy nie łączy w rzeczywistości dwóch tablic, ale zwraca nową, wypełnioną kolejno wpisami z obu podanych tablic. Przekształcanie wymiarów tablicy za pomocą np.reshape(...)jest możliwe tylko pod warunkiem, że liczba elementów w tablicy nie ulegnie zmianie. Te okoliczności wynikają z faktu, że tablice NumPy muszą być widokami na ciągłych buforach pamięci . Pakiet zastępczy o nazwie Blaze próbuje przezwyciężyć to ograniczenie.

Algorytmy , których nie można wyrazić jako operacje wektorowe, zwykle działają powoli, ponieważ muszą być zaimplementowane w „czystym Pythonie”, podczas gdy wektoryzacja może zwiększyć złożoność pamięci niektórych operacji ze stałych do liniowych, ponieważ muszą być tworzone tymczasowe tablice, które są tak duże, jak wejścia. Kompilacja kodu numerycznego w czasie wykonywania została zaimplementowana przez kilka grup, aby uniknąć tych problemów; rozwiązania open source współpracujące z NumPy obejmują scipy.weave, numexpr i Numba . Cython i Pythran są alternatywami do kompilacji statycznej.

Wiele nowoczesnych aplikacji do obliczeń naukowych na dużą skalę ma wymagania, które przekraczają możliwości macierzy NumPy. Na przykład macierze NumPy są zwykle ładowane do pamięci komputera , która może mieć niewystarczającą pojemność do analizy dużych zbiorów danych . Ponadto operacje NumPy są wykonywane na pojedynczym procesorze . Jednak wiele operacji algebry liniowej można przyspieszyć, wykonując je na klastrach procesorów lub na specjalistycznym sprzęcie, takim jak GPU i TPU , na których opiera się wiele aplikacji do uczenia głębokiego . W rezultacie w ostatnich latach w naukowym ekosystemie Pythona pojawiło się kilka alternatywnych implementacji macierzy, takich jak Dask dla macierzy rozproszonych i TensorFlow lub JAX do obliczeń na procesorach graficznych. Ze względu na swoją popularność często implementują one podzbiór API Numpy'ego lub naśladują go, dzięki czemu użytkownicy mogą zmienić implementację tablicy przy minimalnych zmianach w kodzie. Niedawno wprowadzono biblioteka o nazwie CUPy , przyspieszone przez Nvidia „s CUDA ram, również wykazało potencjał szybciej obliczeniowej, będąc” zamiennik "z NumPy.

Przykłady

Tworzenie tablicy
>>> import numpy as np
>>> x = np.array([1, 2, 3])
>>> x
array([1, 2, 3])
>>> y = np.arange(10)  # like Python's list(range(10)), but returns an array
>>> y
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Podstawowe operacje
>>> a = np.array([1, 2, 3, 6])
>>> b = np.linspace(0, 2, 4)  # create an array with four equally spaced points starting with 0 and ending with 2.
>>> c = a - b
>>> c
array([ 1.        ,  1.33333333,  1.66666667,  4.        ])
>>> a**2
array([ 1,  4,  9, 36])
Funkcje uniwersalne
>>> a = np.linspace(-np.pi, np.pi, 100) 
>>> b = np.sin(a)
>>> c = np.cos(a)
Algebra liniowa
>>> from numpy.random import rand
>>> from numpy.linalg import solve, inv
>>> a = np.array([[1, 2, 3], [3, 4, 6.7], [5, 9.0, 5]])
>>> a.transpose()
array([[ 1. ,  3. ,  5. ],
       [ 2. ,  4. ,  9. ],
       [ 3. ,  6.7,  5. ]])
>>> inv(a)
array([[-2.27683616,  0.96045198,  0.07909605],
       [ 1.04519774, -0.56497175,  0.1299435 ],
       [ 0.39548023,  0.05649718, -0.11299435]])
>>> b =  np.array([3, 2, 1])
>>> solve(a, b)  # solve the equation ax = b
array([-4.83050847,  2.13559322,  1.18644068])
>>> c = rand(3, 3) * 20  # create a 3x3 random matrix of values within [0,1] scaled by 20
>>> c
array([[  3.98732789,   2.47702609,   4.71167924],
       [  9.24410671,   5.5240412 ,  10.6468792 ],
       [ 10.38136661,   8.44968437,  15.17639591]])
>>> np.dot(a, c)  # matrix multiplication
array([[  53.61964114,   38.8741616 ,   71.53462537],
       [ 118.4935668 ,   86.14012835,  158.40440712],
       [ 155.04043289,  104.3499231 ,  195.26228855]])
>>> a @ c # Starting with Python 3.5 and NumPy 1.10
array([[  53.61964114,   38.8741616 ,   71.53462537],
       [ 118.4935668 ,   86.14012835,  158.40440712],
       [ 155.04043289,  104.3499231 ,  195.26228855]])
Tensory
>>> M = np.zeros(shape=(2, 3, 5, 7, 11))
>>> T = np.transpose(M, (4, 2, 1, 3, 0))
>>> T.shape
(11, 5, 3, 7, 2)
Włączenie z OpenCV
>>> import numpy as np
>>> import cv2
>>> r = np.reshape(np.arange(256*256)%256,(256,256))  # 256x256 pixel array with a horizontal gradient from 0 to 255 for the red color channel
>>> g = np.zeros_like(r)  # array of same size and type as r but filled with 0s for the green color channel
>>> b = r.T # transposed r will give a vertical gradient for the blue color channel
>>> cv2.imwrite('gradients.png', np.dstack([b,g,r]))  # OpenCV images are interpreted as BGR, the depth-stacked array will be written to an 8bit RGB PNG-file called 'gradients.png'
True
Wyszukiwanie najbliższego sąsiedztwa — iteracyjny algorytm Pythona i zwektoryzowana wersja NumPy
>>> # # # Pure iterative Python # # #
>>> points = [[9,2,8],[4,7,2],[3,4,4],[5,6,9],[5,0,7],[8,2,7],[0,3,2],[7,3,0],[6,1,1],[2,9,6]]
>>> qPoint = [4,5,3]
>>> minIdx = -1
>>> minDist = -1
>>> for idx, point in enumerate(points):  # iterate over all points
...     dist = sum([(dp-dq)**2 for dp,dq in zip(point,qPoint)])**0.5  # compute the euclidean distance for each point to q
...     if dist < minDist or minDist < 0:  # if necessary, update minimum distance and index of the corresponding point
...         minDist = dist
...         minIdx = idx

>>> print('Nearest point to q: {0}'.format(points[minIdx]))
Nearest point to q: [3, 4, 4]

>>> # # # Equivalent NumPy vectorization # # #
>>> import numpy as np
>>> points = np.array([[9,2,8],[4,7,2],[3,4,4],[5,6,9],[5,0,7],[8,2,7],[0,3,2],[7,3,0],[6,1,1],[2,9,6]])
>>> qPoint = np.array([4,5,3])
>>> minIdx = np.argmin(np.linalg.norm(points-qPoint,axis=1))  # compute all euclidean distances at once and return the index of the smallest one
>>> print('Nearest point to q: {0}'.format(points[minIdx]))
Nearest point to q: [3 4 4]

Zobacz też

Bibliografia

Dalsza lektura

  • Bressert, Eli (2012). Scipy i Numpy: przegląd dla programistów . O'Reilly. Numer ISBN 978-1-4493-0546-8.
  • McKinney, Wes (2017). Python do analizy danych: walka o dane z Pandas, NumPy i IPython (wyd. 2). Sewastopol: O'Reilly. Numer ISBN 978-1-4919-5766-0.
  • VanderPlas, Jake (2016). „Wprowadzenie do NumPy”. Podręcznik Python Data Science: podstawowe narzędzia do pracy z danymi . O'Reilly. s. 33–96. Numer ISBN 978-1-4919-1205-8.

Zewnętrzne linki