6.7. Görünümler ve kopyalar¶
Bir görünüm, kaynakla aynı veri bloğuna açılan ikinci bir penceredir. Hiçbir veri kopyalanmaz; görünüm yeni bir tanımlayıcı tutar (kendi şekli, adımları ve dtype değeri) ancak arabelleği paylaşır. Görünümler esasen bedavadır.
Bir kopya, kameradan yeni bir arabellek ister ve kaynağı dolaşarak onu doldurur. Kopyalar hem zaman hem de RAM maliyetine yol açar.
Şekil değiştiren yöntemlerin çoğu görünüm üretir. Veriyi dönüştürenlerin çoğu kopya üretir. Hangisinin hangisi olduğunu bilmek, yoğun bir döngünün kamerayı RAM’siz bırakıp bırakmayacağına karar verir.
6.7.1. Reshape¶
reshape(), istenen şekle sahip bir dizi döndürür. Toplam öğe sayısı değişmemelidir, aksi takdirde ValueError yükseltilir:
a = np.arange(12, dtype=np.uint8)
m = a.reshape((3, 4))
Sonuç bir görünümdür – m ve a verisini paylaşır. m[0, 0] = 99 aracılığıyla yazmak a[0] değerini de değiştirir.
shape özniteliğine yeni bir demet atamak aynı işlemin kısaltmasıdır:
a = np.arange(9)
a.shape = (3, 3)
6.7.2. Transpose¶
transpose() (veya .T kısayolu) eksenleri tersine çevirir. Adımları tersine çevirerek uygulanır – hiçbir veri taşınmaz:
m = np.arange(6, dtype=np.uint8).reshape((2, 3))
t = m.T # shape (3, 2), shares m's buffer
Transpoze edilmiş bir görünüm, veri bloğunu bitişik biçimde dolaşmaz. Yukarıdaki t görünümünü satır satır okumak, baytların yerleştirildiği alttaki 0, 1, 2, 3, 4, 5 sırasını değil, 0, 3, 1, 4, 2, 5 bellek konumlarını ziyaret eder. Sıradan aritmetik ve indirgemeler bunu sorunsuz işler – adımlar üzerinden ilerlerler – ancak tobytes() bunu yapamaz, çünkü kopyalamadan alttaki arabelleği doğrudan geri verir. Arabelleğin tuttuğu baytlar, görünümün şeklinin ima ettiği sırayla eşleşmez, bu yüzden bu yöntem bitişik olmayan herhangi bir görünümde ValueError yükseltir. Baytlara transpoze edilmiş sırada ihtiyaç duyulduğunda, önce yeni bir bitişik kopya oluşturmaya zorlayın:
bytes_out = t.copy().tobytes()
6.7.3. Flatten ve flat¶
flatten(), dizinin 1 boyutlu bir kopyasını döndürür:
f = m.flatten() # new dense 1-D ndarray
Son ekseni önce dolaşmak için order='C' (varsayılan), ilk ekseni önce dolaşmak için order='F' geçirin:
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)
flat, yineleyici biçimidir. Düz bir kopya ayırmadan, herhangi dereceli bir ndarray nesnesinin her öğesini skaler olarak verir:
for x in m.flat:
print(x)
Uygulamanın her öğeyi dolaşması gerektiğinde flat tercih edin; başka bir fonksiyona vermek üzere yoğun bir 1 boyutlu arabelleğe ihtiyacı olduğunda flatten() kullanın.
6.7.4. Yineleme¶
1 boyutlu bir diziyi yinelemek skalerler verir; daha yüksek dereceli bir diziyi yinelemek (n-1) boyutlu görünümler verir:
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])
Bir matrisin yinelenmesiyle verilen satırlar görünümlerdir, dolayısıyla onları değiştirmek kaynağı değiştirir.
6.7.5. Kopyalar¶
copy(), değişiklikleri orijinali etkilemeyen bağımsız bir ndarray elde etmenin açık yoludur. Yeni bir arabellek ayrılır ve kaynak ona dolaşılır:
c = a.copy()
tobytes(), dizinin veri bloğuyla bellek paylaşan bir bytearray döndürür. bytearray aracılığıyla yazmak diziyi yerinde değiştirir. Dizi yoğun değilse (dilimlenmiş bir görünüm, bir transpoze, …) ValueError yükseltir.
tolist(), içeriği olası iç içe geçmiş bir Python list olarak döndürür. Küçük sonuçları serileştirmek için kullanışlıdır; büyük olanlar için pahalıdır, çünkü her öğe ayrı bir Python nesnesi olur.
6.7.6. Hangi işlemler hangisini döndürür¶
Tam kural:
Aşağıdaki işlemler görünüm döndürür:
dilimleme –
a[1:5],a[::2],m[:, 0];daha yüksek dereceli bir dizinin tek eksenli indekslenmesi –
m[0];n boyutlu bir dizinin yinelenmesi;
reshape(), istenen yerleşim uyumlu olduğunda;transpose()/.T;asarray(), dtype eşleştiğinde.
Aşağıdaki işlemler kopya döndürür:
mantıksal indeksleme –
a[mask];aritmetik –
a + b,a * 2,np.sin(a);array()– başka bir diziden bile olsa daima kopyalar;
Açık bir kopyaya yalnızca gerçekten bağımsız bir arabelleğe ihtiyaç duyulduğunda başvurun. Sınırlı RAM’e sahip bir kamerada, bir görünümle bir kopya arasındaki fark çoğu zaman sığan kodla sığmayan kod arasındaki farktır.