6.7. Nézetek és másolatok¶
Egy nézet egy második ablak ugyanarra az adatblokkra, mint a forrás. Nem másolódik adat; a nézet egy friss leírót tart (saját alakkal, lépésközökkel és dtype-pal), de osztozik a pufferen. A nézetek lényegében ingyenesek.
Egy másolat egy új puffert kér a kamerától, és bejárja a forrást, hogy feltöltse. A másolatok időbe és RAM-ba is kerülnek.
A legtöbb alakváltoztató metódus nézeteket állít elő. A legtöbb adatátalakító másolatokat. Annak tudása, hogy melyik melyik, eldönti, hogy egy forró ciklus kifogyasztja-e a kamerát a RAM-ból.
6.7.1. Reshape¶
A reshape() a kért alakú tömböt adja vissza. Az elemek teljes számának változatlannak kell maradnia, különben ValueError kivétel keletkezik:
a = np.arange(12, dtype=np.uint8)
m = a.reshape((3, 4))
Az eredmény egy nézet – az m és az a megosztja az adatokat. Az m[0, 0] = 99 keresztüli írás az a[0]-t is megváltoztatja.
Egy új n-es rendezett rekord hozzárendelése a shape attribútumhoz ugyanennek a műveletnek a rövidített formája:
a = np.arange(9)
a.shape = (3, 3)
6.7.2. Transzponálás¶
A transpose() (vagy a .T rövidítés) megfordítja a tengelyeket. A lépésközök megfordításával valósul meg – nem mozog adat:
m = np.arange(6, dtype=np.uint8).reshape((2, 3))
t = m.T # shape (3, 2), shares m's buffer
Egy transzponált nézet nem összefüggően járja be az adatblokkot. A fenti t soronkénti olvasása a 0, 3, 1, 4, 2, 5 memóriapozíciókat látogatja meg, nem azt az alapul szolgáló 0, 1, 2, 3, 4, 5 sorrendet, amelyben a bájtok elhelyezkednek. A közönséges aritmetika és a redukciók ezt jól kezelik – a lépésközökön keresztül lépkednek –, de a tobytes() nem, mert az alapul szolgáló puffert közvetlenül, másolás nélkül adja vissza. A pufferben lévő bájtok nem felelnek meg annak a sorrendnek, amelyet a nézet alakja sugall, így a metódus bármilyen nem összefüggő nézet esetén ValueError kivételt vált ki. Ha a bájtokra a transzponált sorrendben van szükség, először kényszeríts ki egy friss összefüggő másolatot:
bytes_out = t.copy().tobytes()
6.7.3. Flatten és flat¶
A flatten() a tömb egy 1 dimenziós másolatát adja vissza:
f = m.flatten() # new dense 1-D ndarray
Add meg az order='C' (alapértelmezett) értéket az utolsó tengely előbb történő bejárásához, vagy az order='F' értéket az első tengely előbb történő bejárásához:
m = np.arange(6, dtype=np.uint8).reshape((2, 3))
# m = [[0, 1, 2],
# [3, 4, 5]]
m.flatten() # array([0, 1, 2, 3, 4, 5], dtype=uint8)
m.flatten(order='F') # array([0, 3, 1, 4, 2, 5], dtype=uint8)
A flat az iterátor forma. Bármilyen rangú ndarray minden elemét skalárként adja át, anélkül, hogy lapos másolatot foglalna:
for x in m.flat:
print(x)
Ha az alkalmazásnak be kell járnia minden elemet, részesítsd előnyben a flat-et; ha egy sűrű 1 dimenziós pufferre van szüksége, amelyet átadhat egy másik függvénynek, használd a flatten()-t.
6.7.4. Iteráció¶
Egy 1 dimenziós tömb iterálása skalárokat ad; egy magasabb rangú tömb iterálása (n-1) dimenziós nézeteket ad:
m = np.array([[0, 1, 2], [3, 4, 5]], dtype=np.uint8)
for row in m:
print(row) # array([0, 1, 2]), array([3, 4, 5])
A mátrix iterálása által adott sorok nézetek, így a módosításuk a forrást módosítja.
6.7.5. Másolatok¶
A copy() az explicit módja annak, hogy egy független ndarray-t kapj, amelynek módosításai nem érintik az eredetit. Egy új puffer foglalódik, és a forrás kerül bejárásra bele:
c = a.copy()
A tobytes() egy bytearray objektumot ad vissza, amely a tömb adatblokkjával megosztja a memóriát. A bytearray-en keresztüli írások helyben módosítják a tömböt. ValueError kivételt vált ki, ha a tömb nem sűrű (szeletelt nézet, transzponálás, …).
A tolist() a tartalmat egy esetlegesen beágyazott Python list formájában adja vissza. Hasznos kis eredmények sorosításához; nagyok esetén költséges, mert minden elem külön Python-objektummá válik.
6.7.6. Melyik művelet mit ad vissza¶
A teljes szabály:
A következő műveletek nézeteket adnak vissza:
szeletelés –
a[1:5],a[::2],m[:, 0];egy magasabb rangú tömb egyetlen tengely menti indexelése –
m[0];egy n dimenziós tömb iterálása;
reshape(), ha a kért elrendezés kompatibilis;transpose()/.T;asarray(), ha a dtype egyezik.
A következő műveletek másolatokat adnak vissza:
logikai indexelés –
a[mask];aritmetika –
a + b,a * 2,np.sin(a);array()– mindig másol, még egy másik tömbből is;
Csak akkor nyúlj explicit másolathoz, ha valóban szükség van egy független pufferre. Egy korlátozott RAM-mal rendelkező kamerán a nézet és a másolat közötti különbség gyakran a beférő kód és a be nem férő kód közötti különbség.