a dizilimin içindeki 0 olmayan elemanların sayısını bulmaya çalışalım. Bunun için Matlab'te nnz var. Python için olanını biz yazacağız.

İki çeşit yaklaşım olabilir:

len(where(a!=0)[0])  # Yöntem 1
(a!=0).sum()         # Yöntem 2

Acaba hangisi daha hızlı?

IPython konsolunda denemeye başlayalım:

In [1]: from numpy import array, where

In [2]: a = array([0,1,4,76,3,0,4,67,9,5,3,9,0,5,23,3,0,5,3,3,0,5,0])

In [3]: %timeit len(where(a!=0)[0])
100000 loops, best of 3: 2.75 µs per loop

In [4]: %timeit (a!=0).sum()
100000 loops, best of 3: 5.15 µs per loop

%timeit ile birçok kez kodu deneyim en iyi sonuçları görmek mümkün. Yazacağınız kodları kolaylıkla hız testine tabi tutabilirsiniz.

Görünüşe göre ilki daha hızlı. a'nın boyunu büyütelim ve tekrar deneyelim:

In [5]: from numpy import hstack

In [6]: a = hstack([a,a,a,a,a,a,a,a,a,a,a,a])

In [7]: %timeit len(where(a!=0)[0])
100000 loops, best of 3: 4.86 µs per loop

In [8]: %timeit (a!=0).sum()
100000 loops, best of 3: 10.3 µs per loop

İlki hala daha hızlı görünüyor. a'nın boyunu daha da büyütelim ve yeniden deneyelim ve bunu tekrarlayalım:

In [9]: a = hstack([a,a,a,a,a,a,a,a,a,a,a,a])

In [10]: %timeit len(where(a!=0)[0])
10000 loops, best of 3: 30.6 µs per loop

In [11]: %timeit (a!=0).sum()
100000 loops, best of 3: 13.4 µs per loop

In [12]: a = hstack([a,a,a,a,a,a,a,a,a,a,a,a])

In [13]: %timeit len(where(a!=0)[0])
1000 loops, best of 3: 362 µs per loop

In [14]: %timeit (a!=0).sum()
10000 loops, best of 3: 104 µs per loop

a'nın boyu büyüdüğünde ikinci yöntem daha verimli görünüyor. Çünkü where yeni vektörün boyutunu baştan bilmediğinden vektörü ilklendiremiyor.

Güncelleme: Yeni fark ettim ki zaten numpy içinde bu işi yapan hazır fonksiyon varmış:

In [15]: from numpy import count_nonzero
         a = array([0,1,4,76,3,0,4,67,9,5,3,9,0,5,23,3,0,5,3,3,0,5,0])
         %timeit count_nonzero(a)
1000000 loops, best of 3: 238 ns per loop

Hız müthiş fark etti!

Not: Kaynak için tıklayınız.