python - Find number of zeros before non-zero in a numpy array -
i have numpy array a
. return number of zeros before non-zero in a
in efficient way in loop.
if a = np.array([0,1,2])
np.nonzero(a)[0][0]
returns 1. if a = np.array([0,0,0])
doesn't work (i answer 3 in case). , if big , first non-zero near beginning seems inefficient.
here's iterative cython version, may best bet if serious bottleneck
# saved file count_leading_zeros.pyx import numpy np cimport numpy np cimport cython dtype = np.int ctypedef np.int_t dtype_t @cython.boundscheck(false) def count_leading_zeros(np.ndarray[dtype_t, ndim=1] a): cdef int elements = a.size cdef int = 0 cdef int count = 0 while < elements: if a[i] == 0: count += 1 else: return count += 1 return count
this similar @mtrw's answer indexing @ native speeds. cython bit sketchy there may further improvements made.
a quick test of extremely favourable case ipython few different methods
in [1]: import numpy np in [2]: import pyximport; pyximport.install() out[2]: (none, <pyximport.pyximport.pyximporter @ 0x53e9250>) in [3]: import count_leading_zeros in [4]: %paste def count_leading_zeros_python(x): ctr = 0 k in x: if k == 0: ctr += 1 else: return ctr return ctr ## -- end pasted text -- in [5]: = np.zeros((10000000,), dtype=np.int) in [6]: a[5] = 1 in [7]: in [7]: %timeit np.min(np.nonzero(np.hstack((a, 1)))) 10 loops, best of 3: 91.1 ms per loop in [8]: in [8]: %timeit np.where(a)[0][0] if np.shape(np.where(a)[0])[0] != 0 else np.shape(a)[0] 10 loops, best of 3: 107 ms per loop in [9]: in [9]: %timeit count_leading_zeros_python(a) 100000 loops, best of 3: 3.87 µs per loop in [10]: in [10]: %timeit count_leading_zeros.count_leading_zeros(a) 1000000 loops, best of 3: 489 ns per loop
however i'd use if had evidence (with profiler) bottleneck. many things may seem inefficient never worth time fix.
Comments
Post a Comment