Если вас интересует самое быстрое выполнение, вы заранее знаете, какое значение (а) нужно искать, и ваш массив является 1D, или вы иным образом интересуетесь результатом для уплощенного массива (в этом случае ввод функции должен будь np.flatten(arr)
скорее чем просто arr
) тогда Нумба твой друг
import numba as nb
@nb.jit
def count_nb(arr, value):
result = 0
for x in arr:
if x == value:
result += 1
return result
или для очень больших массивов, где распараллеливание может быть полезным:
@nb.jit(parallel=True)
def count_nbp(arr, value):
result = 0
for i in nb.prange(arr.size):
if arr[i] == value:
result += 1
return result
Сравнительный анализ их np.count_nonzero()
(который также имеет проблему создания временного массива, которого можно избежать) и np.unique()
решения на основе
import numpy as np
def count_np(arr, value):
return np.count_nonzero(arr == value)
import numpy as np
def count_np2(arr, value):
uniques, counts = np.unique(a, return_counts=True)
counter = dict(zip(uniques, counts))
return counter[value] if value in counter else 0
для ввода, созданного с помощью:
def gen_input(n, a=0, b=100):
return np.random.randint(a, b, n)
получены следующие графики (второй ряд графиков - это увеличение при более быстром подходе):
Показано, что решение на основе Numba заметно быстрее, чем аналоги NumPy, и для очень больших входов параллельный подход быстрее, чем наивный.
Полный код доступен здесь .