Örnek sorular
Aipy Numpy Vectorization BroadcastingZorluk 1
NumPy broadcasting'de iki boyut, shape tuple'larının hangi ucundan başlayarak karşılaştırılır?
- aSondan (en sağdaki boyuttan); eksik baştaki boyutlar 1 sayılır.✓
- bBaştan (en soldaki boyuttan); eksik sondaki boyutlar 1 sayılır. Bu, NumPy'ın shape hizalaması için kullandığı gerçek karşılaştırma yönünü tersine çevirir.
- cOrtadan dışa doğru, önce en büyük boyut karşılaştırılır.
- dBoyutlar hiç karşılaştırılmaz; sadece toplam eleman sayısı eşleşmelidir.
Açıklama:Broadcasting, shape'leri sondan hizalar ve geriye doğru ilerler; bir dizinin boyutu daha azsa, eksik baştaki boyutlar örtük olarak 1 kabul edilir. (b) yönü ters çeviriyor. (c) ve (d) broadcasting'in kullanmadığı mekanizmaları anlatıyor.
Aipy Numpy Vectorization BroadcastingZorluk 1
import numpy as np
a = np.ones((3, 4))
b = np.array([10, 20, 30, 40])
result = a + b
result.shape nedir?
- a(4, 4), çünkü
b kendi uzunluğu kadar bir kez daha tekrarlanır. - b(3, 4), çünkü
b'nin (4,) şekli (1, 4) olarak ele alınır ve 3 satıra yayılır.✓ - cBu bir
ValueError fırlatır, çünkü a ve b aynı sayıda boyuta sahip değildir. - d(3,), çünkü
b, a'nın ilk boyutuna uyacak şekilde küçültülür.
Açıklama:b'nin şekli (4,)'tür ve bu, a'nın son boyutuyla (yine 4) hizalanır; eksik baştaki boyut 1 kabul edilir, böylece b (1, 4)'e yayılır ve sonra 3 satırın tamamına gerilir, sonuç (3, 4) olur. (a) şekli yanlış hesaplıyor. (c) boyut sayısının tam eşleşmesi gerektiğini yanlış varsayıyor. (d) broadcasting değil, indirgemeyi anlatıyor.
Aipy Numpy Vectorization BroadcastingZorluk 2
import numpy as np
a = np.ones((3, 4))
c = np.array([1, 2, 3])
result = a + c
Ne olur?
- a
c otomatik olarak transpoze edilir ve sütun olarak (3, 4)'e yayılır. - b
result (3, 4) şeklinde olur, c 4 sütuna yayılır. - cBu bir
ValueError fırlatır, çünkü son boyutlar (4'e karşı 3) eşit değildir ve hiçbiri 1 değildir.✓ - d
result (3, 3) şeklinde olur, çünkü NumPy a'yı c'nin uzunluğuna göre kırpar. Bu, NumPy'ın aritmetik sırasında shape uyuşmazlıklarını nasıl çözdüğüne dair makul görünen ama yanlış bir tariftir.
Açıklama:a'nın şekli (3, 4), c'ninki (3,)'tür; son boyutları karşılaştırınca 4'e karşı 3 çıkar, bunlar eşit değildir ve hiçbiri 1 değildir, bu yüzden broadcasting bir ValueError ile başarısız olur. (a) ve (d), broadcasting'in üretmediği sonuçları anlatıyor; NumPy şekilleri uydurmak için diziyi asla otomatik transpoze etmez ya da kırpmaz. (b), yalnızca c'nin şekli (4,) olsaydı ortaya çıkacak sonuçtur, (3,) değil.
Aipy Numpy Vectorization BroadcastingZorluk 1
Bir NumPy dizisine Python skaleri eklediğinizde, ör. arr + 5, broadcasting skaleri nasıl ele alır?
- aSkaler önce
arr ile uyumlu şekilde tek elemanlı bir diziye sarılmadıkça hata verir. - bSadece
arr'ın ilk elemanına eklenir, geri kalanı değişmeden kalır. - cÖnceden
arr'ın boyut boyutları kopyalanarak tam olarak arr'ın şekline eşit bir diziye dönüştürülür. - dŞekli
() (sıfır boyut) olarak kabul edilir; bu da arr'ın her boyutuna karşı yayılır.✓
Açıklama:Bir skaler 0 boyutlu bir dizi gibi davranır; broadcasting, (var olmayan) her boyutunu 1 sayar, böylece arr'ın herhangi bir şekline gerilir. (a) ve (b), var olmayan kısıtlamalar ya da davranışlar anlatıyor. (c) kavramsal sonucu doğru anlatsa da mekanizmayı yanlış tarif ediyor — önceden açıkça şekil kopyalayan bir dizi oluşturulmaz.
Aipy Numpy Vectorization BroadcastingZorluk 1
a + b gibi vektörize bir NumPy işlemi, elemanlar üzerinde eşdeğer bir Python for döngüsünden neden tipik olarak çok daha hızlıdır?
- aElemanlar üzerindeki döngü derlenmiş C kodu içinde çalışır, böylece eleman başına Python bytecode dispatch'i ve tip kontrolü ek yükü olmaz.✓
- bNumPy işlemi otomatik olarak birden fazla CPU çekirdeğinde çalıştırır, Python döngüsü ise her zaman tek çekirdektir.
- cNumPy dizileri elemanları önbelleğe alınmış sonuçlara sahip Python nesneleri olarak saklar, bu yüzden tekrarlanan işlemler ilk çağrıdan sonra bedavadır.
- dPython
for döngüsü her iterasyonda yeni bir liste tahsis eder, vektörize kod bunu tamamen atlar.
Açıklama:NumPy'ın ufunc'ları, dizi verisi üzerinde ham, tekdüze tipli bellek üzerinde çalışan derlenmiş C döngüleriyle iterasyon yapar; bu, düz bir for döngüsünün maruz kaldığı eleman başına Python yorumlayıcı yükünü (bytecode dispatch, dinamik tip kontrolü, nesne kutulama) önler. (b) garanti değildir — çoğu elementwise ufunc varsayılan olarak tek thread çalışır. (c) dizi depolamasını yanlış tarif ediyor; NumPy ham sayısal değerleri saklar, Python nesnelerini değil, ve böyle bir önbellekleme mekanizması yoktur. (d) döngünün yavaşlığının gerçek nedeni değildir.
Aipy Numpy Vectorization BroadcastingZorluk 2
import numpy as np
n = 1_000_000
arr = np.arange(n)
def loop_sum_sq():
total = 0
for x in arr:
total += x * x
return total
def vec_sum_sq():
return np.sum(arr * arr)
Her iki fonksiyon da aynı matematiksel sonucu hesaplıyor. Pratikteki temel fark nedir?
- a
vec_sum_sq, NumPy toplamı rastgele sırayla yaptığı için yuvarlama nedeniyle farklı bir sayısal sonuç üretir. - b
loop_sum_sq çok daha yavaştır, çünkü milyon elemanın her biri için Python yorumlayıcısına yeniden girer; vec_sum_sq çarpma ve toplamayı derlenmiş döngülerde yapar.✓ - c
loop_sum_sq daha hızlıdır, çünkü Python tam sayıları NumPy'ın sabit-genişlik taşma sorunlarını tamamen atlar. - d
n = 1_000_000 için anlamlı bir fark yoktur; her iki yaklaşım da benzer duvar-saati süresi alır.
Açıklama:for x in arr ile iterasyon, tek tek düz Python nesneleri verir ve döngü gövdesini (öznitelik erişimi, çarpma, toplama) milyon elemanın her biri için Python yorumlayıcısı üzerinden çalıştırır, bu görece yavaştır. vec_sum_sq ise çarpmayı ve toplamayı vektörize C-seviyesi işlemler olarak yapar. (a) tam sayı toplamları için yanlıştır — burada sıra yuvarlama getirmez. (c) gerçek bir avantaj değildir; gözlemlenen yavaşlıkla ilgisizdir ve buradaki varsayılan NumPy tamsayı dtype'ı yeterli aralığa sahiptir. (d) bu ölçekte tipik olarak önemli olan farkı (genellikle onlarca kat ya da daha fazla) hafife alıyor.