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;

  • frombuffer();

  • asarray(), dtype eşleştiğinde.

Aşağıdaki işlemler kopya döndürür:

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.