I'm trying to create the most efficient (not nicest/prettiest) way of moving particular values within an np.array() to the back of said array.
I currently have two different solutions:
import numpy as np
from numba import jit
@jit(nopython = True)
def move_to_back_a(a, value):
new_a = []
total_values = 0
for v in a:
if v == value:
total_values += 1
else:
new_a.append(v)
return new_a + [value] * total_values
@jit(nopython = True)
def move_to_back_b(a, value):
total_values = np.count_nonzero(a == value)
ind = a == value
a = a[~ind]
return np.append(a, [value] * total_values)
Which give the following output:
In [7]: move_to_back_a(np.array([2,3,24,24,24,1]), 24)
Out[7]: [2, 3, 1, 24, 24, 24]
In [8]: move_to_back_b(np.array([2,3,24,24,24,1]), 24)
Out[8]: array([ 2, 3, 1, 24, 24, 24], dtype=int64)
It doesn't really matter whether I get back my output as a list or as an array, though I expect that returning an array will be more helpful in my future code.
The current timing on these tests is as follows:
In [9]: %timeit move_to_back_a(np.array([2,3,24,24,24,1]), 24)
2.28 µs ± 20.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [10]: %timeit move_to_back_b(np.array([2,3,24,24,24,1]), 24)
3.1 µs ± 50.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Is there any way to make this code even faster?

np.count_nonzerobeing used in a wrong way \$\endgroup\$