Для более эффективного подхода вот альтернатива numba
:
from numba import njit, int32
@njit
def mode_rand_ties(a):
out = np.zeros(a.shape[1], dtype=int32)
for col in range(a.shape[1]):
z = np.zeros(a[:,col].max()+1, dtype=int32)
for v in a[:,col]:
z[v]+=1
maxs = np.where(z == z.max())[0]
out[col] = np.random.choice(maxs)
return out
Там, где тестирование для массива выше, запустив несколько раз, мы увидим, что мы можем получить либо 3
, либо 4
как режим первого столбца:
mode_rand_ties(a)
# array([4, 3, 0], dtype=int32)
mode_rand_ties(a)
# array([3, 3, 0], dtype=int32)
И, проверив производительность массива в форме (4000, 3)
, мы получаем, что это занимает всего около 40us:
x = np.concatenate([a]*1000, axis=0)
%timeit mode_rand_ties(x)
# 41.1 µs ± 13.2 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Принимая во внимание, что с текущим решением:
%timeit mode_rand(x, axis=0)
# 388 µs ± 23.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)