У меня есть массив indexs. Он очень длинный (>10k), и каждое значение int довольно маленькое (<100). например
indexs = np.array([1, 4, 3, 0, 0, 1, 2, 0]) # int index array
indexs_max = 4 # already known
Теперь я хочу подсчитать появление каждого значения индекса (например, 0 для 3 раз, 1 для 2 раз...) и получить counts как np.array([3, 2, 1, 1, 1]). Я протестировал 4 метода следующим образом:
UPDATE: _test4 — соль @Ch3steR:
indexs = np.random.randint(0, 10, (20000,))
indexs_max = 9
def _test1():
counts = np.zeros((indexs_max + 1, ), dtype=np.int32)
for ind in indexs:
counts[ind] += 1
return counts
def _test2():
counts = np.zeros((indexs_max + 1,), dtype=np.int32)
uniq_vals, uniq_cnts = np.unique(indexs, return_counts=True)
counts[uniq_vals] = uniq_cnts
# this is because some value in range may be missing
return counts
def _test3():
therange = np.arange(0, indexs_max + 1)
counts = np.sum(indexs[None] == therange[:, None], axis=1)
return counts
def _test4():
return np.bincount(indexs, minlength=indexs_max+1)
Запустите 500 раз, их использование времени соответственно 32.499472856521606s, 0.31386804580688477s, 0.14069509506225586s, 0.017721891403198242s. Хотя _test3 является самым быстрым, он использует дополнительную большую память.
Поэтому я прошу любые лучшие методы. Спасибо :) (@Ch3steR)
UPDATE: np.bincount пока кажется оптимальным.






Вы можете использовать np.bincount для подсчета вхождений в массиве.
indexs = np.array([1, 4, 3, 0, 0, 1, 2, 0])
np.bincount(indexs)
# array([3, 2, 1, 1, 1])
# 0's 1's 2's 3's 4's count
Есть нюанс np.bincount(x).size == np.amax(x)+1
Пример:
indexs = np.array([5, 10]) np.bincount(indexs) # array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) # 5's 10's countЗдесь он будет подсчитывать вхождения от 0 до максимума в массиве, обходной путь может быть
c = np.bincount(indexs) # indexs is [5, 10] c = c[c>0] # array([1, 1]) # 5's 10's countЕсли у вас нет пропущенных значений, то есть от
0доyour_max, вы можете использоватьnp.bincount.
Еще одно предостережение:
Из документов:
Подсчитайте количество вхождений каждого значения в массив неотрицательных целых чисел.
Большой!
test4isbincount: ` использование времени в (с): тест 1: 32,499472856521606 тест 2: 0,31386804580688477 тест 3: 0,14069509506225586 тест 4: 0,017721891403198242 `