Very simple. I am trying to count the number of non-zero values in an array in NumPy jit compiled with Numba (njit()
). The following I've tried is not allowed by Numba.
a[a != 0].size
np.count_nonzero(a)
len(a[a != 0])
len(a) - len(a[a == 0])
I don't want to use for loops if there is still a faster, more pythonic and elegant way.
For that commenter that wanted to see a full code example...
import numpy as np
from numba import njit
@njit()
def n_nonzero(a):
return a[a != 0].size
You may also consider, well, counting the nonzero values:
import numba as nb
@nb.njit()
def count_loop(a):
s = 0
for i in a:
if i != 0:
s += 1
return s
I know it seems wrong, but bear with me:
import numpy as np
import numba as nb
@nb.njit()
def count_loop(a):
s = 0
for i in a:
if i != 0:
s += 1
return s
@nb.njit()
def count_len_nonzero(a):
return len(np.nonzero(a)[0])
@nb.njit()
def count_sum_neq_zero(a):
return (a != 0).sum()
np.random.seed(100)
a = np.random.randint(0, 3, 1000000000, dtype=np.uint8)
c = np.count_nonzero(a)
assert count_len_nonzero(a) == c
assert count_sum_neq_zero(a) == c
assert count_loop(a) == c
%timeit count_len_nonzero(a)
# 5.94 s ± 141 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit count_sum_neq_zero(a)
# 848 ms ± 80.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit count_loop(a)
# 189 ms ± 4.41 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
It is in fact faster than np.count_nonzero
, which can get quite slow for some reason:
%timeit np.count_nonzero(a)
# 4.36 s ± 69.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加