A ndarray
rögzített méretű adatpufferrel jön létre – éppen akkora, hogy az elemeket reprezentáló bájtokat tárolja.
arr.nbytes == arr.itemsize * arr.size
A arr.resize
helyben módosíthatja a tömböt. De olvassa el a dokumentumait, hogy megtudja a korlátokat, különösen a saját adatok birtoklásával kapcsolatban. Ez egyike azon kevés helyi műveleteknek, és nem használják olyan gyakran.
Ezzel szemben a Python-lista az objektummutatókat egy pufferben tárolja. A pufferben van némi növekedési lehetőség, amely lehetővé teszi a hatékony append
. Csak egy új mutatót kell hozzáadnia a pufferhez. Amikor a puffer megtelik, új nagyobb puffert foglal le, és lemásolja a mutatókat.
Egy 1d tömb esetén a ndarray
és list
pufferei hasonlóak lesznek, legalább 4 vagy 8 bájtos numerikus dtype esetén. A többdimenziós tömbök esetében azonban az adatpuffer nagyon nagy lehet (az összes dimenzió szorzata), míg egy egyenértékű beágyazott tömb felső puffere csak a listák külső rétegére (a „sorokra”) mutató mutatókat tartalmaz.
Az objektum dtype tömbök listaként tárolják a mutatókat, de az adatpuffer továbbra is rögzített méretű (nincs növekedési terület). A teljesítmény a numerikus tömbök és listák között rejlik.
El tudom képzelni, hogy írok egy inplace hozzáfűzést, amely a resize
metódust használja, majd az új érték(ek) másolása a 0 kitöltésekre.
In [96]: arr = np.array([[1,3],[2,7]])
In [97]: arr.resize(3,2)
In [98]: arr
Out[98]:
array([[1, 3],
[2, 7],
[0, 0]])
In [99]: arr[-1,:] = 10,11
In [100]: arr
Out[100]:
array([[ 1, 3],
[ 2, 7],
[10, 11]])
De figyeljük meg, mi történik az értékekkel, ha átméretezünk egy belső tengelyt:
In [101]: arr = np.array([[1,3],[2,7]])
In [102]: arr.resize(2,3)
In [103]: arr
Out[103]:
array([[1, 3, 2],
[7, 0, 0]])
Tehát ez a fajta hozzáfűzés meglehetősen korlátozott a concatenate
-hez (és annak összes 'verem' származékához) képest.
Megnézted a np.append
kódját? Miután megbizonyosodott arról, hogy az argumentumok tömbök, és módosítja az alakjukat, a következőket teszi:
concatenate((arr, values), axis=axis)
Más szóval, ez csak egy alternatív módja a concatenate
hívásának. Valószínűleg ez a legjobb egyetlen érték hozzáadásához egy 1d tömbhöz. Nem szabad ismételten használni egy ciklusban, pontosan azért, mert új tömböt ad vissza, és így viszonylag drága. Ellenkező esetben a használata sok felhasználót megzavar. Néhányan figyelmen kívül hagyják a tengely paramétert. Másoknak gondjuk van a megfelelő „üres” tömb létrehozásával. A Concatenate-nek is vannak ilyen problémái, de legalább a felhasználóknak tudatosan kell foglalkozniuk az alakzatok illesztésével.
A np.insert
sokkal bonyolultabb. Különböző dolgokat hajt végre attól függően, hogy az indexek (obj
) számok, szeletek vagy számok listája. Az egyik megközelítés a megfelelő méretű céltömb létrehozása, szeletek másolása az eredetiből, és az értékek beillesztése a megfelelő helyekre. Egy másik, hogy logikai maszkot használunk az értékek megfelelő helyekre másolásához. Mindkettőnek többdimenziósnak kell lennie – egy tengely mentén szúr be, de a többi mérethez a megfelelő slice(None)
-t kell használnia. Ez sokkal bonyolultabb, mint a listabeszúrás, amely egy objektumot (mutatót) szúr be egy helyre az 1d-ben.
15.12.2018