NumPy - NumPy

NumPy
NumPy -logotyp 2020.svg
Ursprungliga författare Travis Oliphant
Utvecklare Gemenskapsprojekt
Initial release As Numeric, 1995 ; som NumPy, 2006 ( 1995 ) ( 2006 )
Stabil frisättning
1.21.1 / 18 juli 2021 ; 36 dagar sedan ( 2021-07-18 )
Förvar Redigera detta på Wikidata
Skrivet i Python , C
Operativ system Plattformsoberoende
Typ Numerisk analys
Licens BSD
Hemsida numpy .org Redigera detta på Wikidata

Numpy (uttalas / n ʌ m p / ( NUM -PY ) eller ibland / n ʌ m p i / ( NUM -pee )) är ett bibliotek för programspråket Python , lägga till stöd för stora, flerdimensionella arrayer och matriser , tillsammans med en stor samling matematiska funktionerhög nivå för att hantera dessa matriser. NumPys förfader, Numeric, skapades ursprungligen av Jim Hugunin med bidrag från flera andra utvecklare. År 2005 skapade Travis Oliphant NumPy genom att införliva funktioner i den konkurrerande Numarray i Numeric, med omfattande modifieringar. NumPy är programvara med öppen källkod och har många bidragsgivare.

Historia

Programmeringsspråket Python var inte ursprungligen utformat för numerisk databehandling, utan lockade tidigt uppmärksamheten hos det vetenskapliga och tekniska samhället. 1995 grundades specialintressegruppen (SIG) matrix-sig i syfte att definiera ett array- datapaket; bland medlemmarna fanns Python -designern och underhållaren Guido van Rossum , som utökade Pythons syntax (i synnerhet indexeringssyntaxen) för att underlätta datormatningen .

En implementering av ett matrispaket slutfördes av Jim Fulton, sedan generaliserad av Jim Hugunin och kallades Numeric (även känd som "Numerical Python extensions" eller "NumPy"). Hugunin, doktorand vid Massachusetts Institute of Technology (MIT), anslöt sig 1997 till Corporation for National Research Initiatives (CNRI) för att arbeta med JPython och lämnade Paul Dubois från Lawrence Livermore National Laboratory (LLNL) att ta över som underhållare. Andra tidiga bidragsgivare inkluderar David Ascher, Konrad Hinsen och Travis Oliphant .

Ett nytt paket som heter Numarray skrevs som en mer flexibel ersättning för Numeric. Precis som Numeric, är den också nu utfasad. Numarray hade snabbare operationer för stora matriser, men var långsammare än Numeric på små, så för en tid användes båda paketen parallellt för olika användningsfall. Den senaste versionen av Numeric (v24.2) släpptes den 11 november 2005, medan den senaste versionen av numarray (v1.5.2) släpptes den 24 augusti 2006.

Det fanns en önskan att få Numeric till Pythons standardbibliotek, men Guido van Rossum bestämde att koden inte kunde underhållas i dess tillstånd då.

I början av 2005 ville NumPy -utvecklaren Travis Oliphant förena gemenskapen kring ett enda matrispaket och överförde Numarrays funktioner till Numeric och släppte resultatet som NumPy 1.0 2006. Detta nya projekt var en del av SciPy . För att undvika att installera det stora SciPy -paketet bara för att få ett array -objekt, separerades detta nya paket och kallades NumPy. Stöd för Python 3 lades till 2011 med NumPy version 1.5.0.

Under 2011 startade PyPy utvecklingen av en implementering av NumPy API för PyPy. Det är ännu inte helt kompatibelt med NumPy.

Funktioner

Numpy riktar sig CPython referensimplementering av Python, som är en icke-optimering bytekod tolk . Matematiska algoritmer som skrivits för denna version av Python går ofta mycket långsammare än kompilerade ekvivalenter. NumPy löser problemet med långsamhet delvis genom att tillhandahålla flerdimensionella matriser och funktioner och operatörer som fungerar effektivt på matriser; att använda dessa kräver att skriva om någon kod, mestadels inre slingor , med NumPy.

Att använda NumPy i Python ger funktionalitet som är jämförbar med MATLAB eftersom de båda tolkas, och de tillåter båda att skriva snabba program så länge de flesta operationer fungerar på matriser eller matriser istället för skalarer . I jämförelse har MATLAB ett stort antal ytterligare verktygslådor, särskilt Simulink , medan NumPy är integrerat med Python, ett mer modernt och komplett programmeringsspråk . Dessutom finns kompletterande Python -paket tillgängliga; SciPy är ett bibliotek som lägger till mer MATLAB-liknande funktioner och Matplotlib är ett plottningspaket som tillhandahåller MATLAB-liknande plottningsfunktioner. Internt förlitar sig både MATLAB och NumPy på BLAS och LAPACK för effektiva linjära algebraberäkningar.

Python -bindningar av de allmänt använda datorseende bibliotek OpenCV utnyttja numpy matriser för att lagra och verka på data. Eftersom bilder med flera kanaler helt enkelt representeras som tredimensionella matriser är indexering, skivning eller maskering med andra matriser mycket effektiva sätt att komma åt specifika pixlar i en bild. NumPy -matrisen som universell datastruktur i OpenCV för bilder, extraherade funktionspunkter , filterkärnor och många fler förenklar programmeringsflödet och felsökningen .

Ndarray -datastrukturen

Kärnfunktionen i NumPy är dess "ndarray", för n -dimensionell array, datastruktur. Dessa matriser är delade vyer över minnet. Till skillnad från Pythons inbyggda listdatastruktur är dessa matriser homogent typade: alla element i en enda array måste vara av samma typ.

Sådana matriser kan också vara visningar till minnesbuffertar som tilldelats av C / C ++ , Cython och Fortran -tillägg till CPython -tolkaren utan att behöva kopiera data runt, vilket ger en viss kompatibilitet med befintliga numeriska bibliotek. Denna funktionalitet utnyttjas av SciPy -paketet, som omsluter ett antal sådana bibliotek (särskilt BLAS och LAPACK). NumPy har inbyggt stöd för minneskartade ndarrays.

Begränsningar

Att infoga eller lägga till poster i en array är inte så trivialt som det är med Pythons listor. Den np.pad(...)rutin att förlänga arrayer faktiskt skapar nya uppsättningar av den önskade formen och utfyllnadsvärden, kopierar den givna uppsättningen in i den nya och returnerar den. NumPys np.concatenate([a1,a2])operation länkar faktiskt inte de två matriserna utan returnerar en ny, fylld med posterna från båda givna matriserna i följd. Att omforma en matrisdimensionalitet med np.reshape(...)är bara möjligt så länge antalet element i matrisen inte ändras. Dessa omständigheter härrör från det faktum att NumPys matriser måste vara synpunkter på sammanhängande minnesbuffertar . Ett ersättningspaket som heter Blaze försöker övervinna denna begränsning.

Algoritmer som inte är uttryckliga som en vektoriserad operation kommer vanligtvis att köra långsamt eftersom de måste implementeras i "ren Python", medan vektorisering kan öka minneskomplexiteten för vissa operationer från konstant till linjär, eftersom temporära matriser måste skapas som är lika stora som ingångar. Körtidssammanställning av numerisk kod har implementerats av flera grupper för att undvika dessa problem; öppen källkodslösningar som samverkar med NumPy inkluderar scipy.weavenumexpr och Numba . Cython och Pythran är statiskt kompilerande alternativ till dessa.

Många moderna storskaliga vetenskapliga dataprogram har krav som överstiger möjligheterna hos NumPy-matriser. Exempelvis laddas NumPy -matriser vanligtvis in i en dators minne , vilket kan ha otillräcklig kapacitet för analys av stora datamängder . Vidare körs NumPy -operationer på en enda CPU . Men många linjär algebra operationer påskyndas genom att köra dem på kluster av processorer eller specialiserade hårdvara, såsom GPUs och TPU , som många djupinlärning applikationer lita på. Som ett resultat har flera alternativa matrisimplementeringar uppstått i det vetenskapliga pythonekosystemet under de senaste åren, till exempel Dask för distribuerade matriser och TensorFlow eller JAX för beräkningar på GPU: er. På grund av dess popularitet implementerar dessa ofta en delmängd av Numpys API eller efterliknar det, så att användare kan ändra sin array -implementering med minimala ändringar av deras kod som krävs. En nyligen introducerade bibliotek som heter CUPy , påskyndas av Nvidia 's CUDA ramverk, har också visat potential för snabbare datorer, som är en' drop-in ersättning "av numpy.

Exempel

Array skapande
>>> 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])
Grundläggande funktioner
>>> 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])
Universella funktioner
>>> a = np.linspace(-np.pi, np.pi, 100) 
>>> b = np.sin(a)
>>> c = np.cos(a)
Linjär algebra
>>> 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]])
Tensorer
>>> 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)
Införlivande med 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
Närmaste grannsökning - Iterativ Python -algoritm och vektoriserad NumPy -version
>>> # # # 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]

Se även

Referenser

Vidare läsning

  • Bressert, Eli (2012). Scipy and Numpy: En översikt för utvecklare . O'Reilly. ISBN 978-1-4493-0546-8.
  • McKinney, Wes (2017). Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython (2nd ed.). Sebastopol: O'Reilly. ISBN 978-1-4919-5766-0.
  • VanderPlas, Jake (2016). "Introduktion till NumPy". Python Data Science Handbook: Viktiga verktyg för att arbeta med data . O'Reilly. s. 33–96. ISBN 978-1-4919-1205-8.

externa länkar