Garfield
YZF Admin
NumPy’de
Bir dizinin
İki boyutlu bir dizide stride sırası, dizinin eksen sırasıyla aynıdır. Aşağıdaki varsayımsal örnekte 2 satır ve 3 sütundan oluşan bir dizi oluşturulur:
Beklenen çıktı şöyledir:
Buradaki
Genel adresleme mantığı iki boyutlu bir dizi için kabaca şöyledir:
Bu hesap, Python seviyesinde elle adres erişimi yapmanız gerektiği anlamına gelmez; NumPy’nin diziyi bellekte nasıl yorumladığını açıklamak için kullanılır.
Beklenen çıktı:
Orijinal dizide satır adımı 24, sütun adımı 8 iken transpoze görünümde bu değerler yer değiştirir.
Dilimleme de stride değerini değiştirebilir:
Beklenen çıktı:
İkinci eksende her iki sütunda bir ilerlenir.
Aşağıdaki değerler birlikte değerlendirilmelidir:
C düzeninde son eksen genellikle bitişik ilerler; Fortran düzeninde ise ilk eksen bitişik olabilir. Ancak yalnızca
Bir diziyi incelerken önce
strides, bir dizide bir sonraki elemana geçmek için bellekte kaç bayt ilerlenmesi gerektiğini gösteren demettir. shape dizinin boyutlarını, strides ise bu boyutlarda ilerlerken bellekteki adım uzunluğunu belirtir. Böylece NumPy, veriyi her zaman kopyalamadan dilimleme ve transpoze gibi işlemleri yönetebilir. strides değerini shape ve itemsize ile birlikte okuyarak bir dizinin bellekte nasıl düzenlendiğini anlayabilirsiniz.Strides değeri nasıl okunur?
Bir dizinin
strides özelliğindeki değerler bayt cinsindendir. Örneğin int64 türündeki bir eleman 8 bayt yer kaplar. Tek boyutlu bir dizide stride değeri 8 ise ardışık elemana geçmek için bellekte 8 bayt ilerlenir.İki boyutlu bir dizide stride sırası, dizinin eksen sırasıyla aynıdır. Aşağıdaki varsayımsal örnekte 2 satır ve 3 sütundan oluşan bir dizi oluşturulur:
Python:
import numpy as np
arr = np.array([[10, 20, 30],
[40, 50, 60]], dtype=np.int64)
print(arr.shape)
print(arr.itemsize)
print(arr.strides)
Beklenen çıktı şöyledir:
Kod:
(2, 3)
8
(24, 8)
Buradaki
(24, 8) şu anlama gelir: aynı satırdaki bir sonraki sütuna geçmek için 8 bayt, bir sonraki satıra geçmek için 24 bayt ilerlenir. Bir satırda 3 adet int64 bulunduğu için satır stride değeri 3 × 8 = 24 olur.Genel adresleme mantığı iki boyutlu bir dizi için kabaca şöyledir:
başlangıç adresi + satır_indeksi × satır_stride + sütun_indeksi × sütun_strideBu hesap, Python seviyesinde elle adres erişimi yapmanız gerektiği anlamına gelmez; NumPy’nin diziyi bellekte nasıl yorumladığını açıklamak için kullanılır.
Transpose ve dilimleme strides değerini nasıl değiştirir?
T ile transpoze edilen görünüm çoğu durumda veriyi kopyalamaz. Yalnızca eksenlerin yorumlanma sırasını değiştirir:
Python:
transposed = arr.T
print(transposed.shape)
print(transposed.strides)
print(transposed)
Beklenen çıktı:
Kod:
(3, 2)
(8, 24)
[[10 40]
[20 50]
[30 60]]
Orijinal dizide satır adımı 24, sütun adımı 8 iken transpoze görünümde bu değerler yer değiştirir.
transposed yeni bir veri kopyası olmak zorunda değildir; aynı belleği farklı stride bilgisiyle okuyabilir.Dilimleme de stride değerini değiştirebilir:
Python:
step_slice = arr[:, ::2]
print(step_slice)
print(step_slice.shape)
print(step_slice.strides)
Beklenen çıktı:
Kod:
[[10 30]
[40 60]]
(2, 2)
(24, 16)
İkinci eksende her iki sütunda bir ilerlenir.
int64 elemanlar 8 bayt olduğundan iki sütunluk adım 16 bayttır. Bu görünümde sütunlar bellekte bitişik değildir; arada kullanılmayan elemanlar vardır.Shape, strides ve bellek düzeni arasındaki fark
Aşağıdaki değerler birlikte değerlendirilmelidir:
| Özellik | Ne anlatır? | Örnek |
|---|---|---|
| shape | Her eksendeki eleman sayısını gösterir. | (2, 3) |
| itemsize | Bir elemanın kaç bayt kullandığını gösterir. | 8 |
| strides | Her eksende bir adım ilerlemek için kaç bayt atlanacağını gösterir. | (24, 8) |
| flags | Dizinin C veya Fortran düzeni gibi bazı bellek özelliklerini bildirir. | C_CONTIGUOUS |
strides değerine bakarak dizinin bütün kullanım maliyetini kesin olarak belirlemek doğru değildir. Görünümün kopya olup olmadığını anlamak için base, bellek paylaşımını incelemek için de uygun NumPy araçlarını kullanmak gerekir.Strides ne zaman önemlidir?
strides özellikle büyük dizilerde performans, bellek kopyaları ve C/C++ gibi dillerle veri paylaşımı incelenirken önem kazanır. Bir görünüm veriyi kopyalamadan oluşturulabilir; bu bellek kullanımını azaltır. Buna karşılık ardışık olmayan stride düzeni bazı işlemlerde daha yavaş olabilir veya bir işlemin önce bitişik bir kopya oluşturmasına neden olabilir.numpy.lib.stride_tricks.as_strided gibi düşük seviyeli araçlar stride bilgisiyle özel görünümler oluşturabilir. Ancak yanlış shape veya stride değerleri geçersiz bellek alanlarının okunmasına, hatalı sonuçlara ve zor teşhis edilen sorunlara yol açabilir. Bu nedenle günlük işlemlerde normal dilimleme, reshape, transpose ve ascontiguousarray gibi güvenli ve açık yöntemleri tercih edin.Bir diziyi incelerken önce
shape, dtype, itemsize ve strides değerlerini birlikte yazdırın. Stride değeri eleman sayısı değil bayt cinsinden bellek adımıdır; en sık yapılan yorum hatası budur.