6.2. ndarray¶
ndarray är typen som håller numeriska data i numpy. Den är två saker i ett: ett enda packat datablock och en liten deskriptor framför det blocket som anger hur det ska läsas.
6.2.1. Inuti lådan¶
Datablocket håller varje element i arrayen ände mot ände, utan något extra mellan dem. Varje element upptar samma antal byte – ett för en array av uint8-värden, två för uint16, fyra för float. En 256-elements uint8-array är exakt 256 byte data; samma 256 tal i en Python-list tar en kilobyte – en 32-bitars plats per element oavsett hur få bitar värdet faktiskt behöver.
Deskriptorn registrerar vad blocket betyder. Fem värden räcker för att beskriva vilken rektangulär array som helst, oavsett hur många dimensioner:
dtype– elementtypen. Bestämmer hur många byte varje element tar och vilket värdeintervall det kan hålla (behandlas på Dtyper).itemsize– bytebredden för ett element, härledd från dtypen.ndim– antalet dimensioner (1 för en vektor, 2 för en matris, 3 för en volym, upp till 4).shape– storleken längs varje dimension som en tupel.strides– hur man stegar genom datablocket för att vandra varje axel. Behandlas på Form och strides.
Det är allt. Varje snabb väg i numpy – aritmetik, reduktioner, broadcasting, slicing – arbetar direkt utifrån dessa fem värden plus datapekaren, utan någon Python-overhead per element.
6.2.2. Vad designen ger¶
Tre egenskaper faller ut ur ”packat block + liten deskriptor” och definierar hur resten av avsnittet beter sig.
Elementvis matematik körs som ett enda anrop. a + b mellan två arrayer med matchande form adderar de två buffertarna och skriver en tredje, allt inuti ett biblioteksanrop. np.sin(a) gör detsamma för sinus av varje element. De aritmetiska operatorerna, jämförelseoperatorerna och bitvisa operatorerna fungerar alla på detta sätt.
Att titta på samma data på ett annat sätt är gratis. Att be om en delregion av en array, eller om samma data utlagd under en annan form, flyttar inga byte. Operationen returnerar en ny deskriptor som pekar på samma datablock. Resultatet kallas en vy – ett andra fönster mot samma underliggande buffert. Att skriva via en vy skriver till källan.
Blandade former fungerar ändå. En kortare array mot en längre, en rad mot en matris, en kolumn mot en rad – numpy ställer upp dem genom broadcasting, en liten uppsättning regler som avgör vilken kort axel som sträcks ut för att matcha den långa. Utsträckningen är virtuell; ingen data dupliceras.
6.2.3. Vad designen kostar¶
Två begränsningar följer av samma design.
Varje element har samma typ. En lista kan hålla en int bredvid en str bredvid en lista med ytterligare tre int-värden; en ndarray kan inte. Dtypen är fastlagd vid konstruktionstillfället. Sidan Dtyper behandlar den lilla uppsättning typer som numpy stöder och de regler som följer av att fixera en.
Att låta en array växa är inte gratis. En lista håller reservplatser i slutet och stöder .append billigt. En ndarray är exakt den storlek den behöver vara; att lägga till skulle innebära att allokera en ny, större buffert och kopiera in det gamla innehållet i den. Det finns ingen append()-metod, med avsikt. Rätt mönster på kameran är att förallokera destinationen i dess slutgiltiga storlek och fylla den; Prestanda behandlar tekniken.
Med en packad typad buffert för datan, en liten deskriptor för metadatan och tre beteendegarantier (snabb elementvis matematik, kopieringsfria alternativa vyer av samma data, och former som broadcastar) är ndarray den grund som resten av kapitlet vilar på. Hur en array faktiskt blir till – från en litteral, från en förfylld allokering, från en buffert i kringutrustning – är nästa praktiska fråga.