It's better to stick to regular NumPy arrays over the chararrays
:
Примечание:
Класс chararray существует для обратной совместимости с
Numarray, не рекомендуется для новых разработок. Начиная с
numpy 1.4, если нужны массивы строк, рекомендуется использовать
массивы dtype object_, string_ или unicode_, и использовать свободный
функции в модуле numpy.char для быстрой векторизованной строки
операции.
Используя обычные массивы, давайте предложим два подхода.
Подход № 1
Мы могли бы использовать np.count_nonzero
для подсчета единиц True
после сравнения с поисковым элементом: 'A'
-
np.count_nonzero(rr=='A')
Подход № 2
С chararray
, содержащим только односимвольные элементы, мы могли бы намного лучше оптимизировать, просматривая его с помощью uint8
dtype, а затем сравнивая и подсчитывая. Подсчет будет намного быстрее, так как мы будем работать с числовыми данными. Реализация будет -
np.count_nonzero(rr.view(np.uint8)==ord('A'))
На Python 2.x
это будет -
np.count_nonzero(np.array(rr.view(np.uint8))==ord('A'))
Задержка
Временные параметры исходных данных выборки и масштабированы до 10,000x
масштабированы -
# Original sample data
In [10]: rr
Out[10]: array(['B', 'B', 'B', 'A', 'B', 'A', 'A', 'A', 'B', 'A'], dtype='<U1')
# @Nils Werner's soln
In [14]: %timeit np.sum(rr == 'A')
100000 loops, best of 3: 3.86 µs per loop
# Approach #1 from this post
In [13]: %timeit np.count_nonzero(rr=='A')
1000000 loops, best of 3: 1.04 µs per loop
# Approach #2 from this post
In [40]: %timeit np.count_nonzero(rr.view(np.uint8)==ord('A'))
1000000 loops, best of 3: 1.86 µs per loop
# Original sample data scaled by 10,000x
In [16]: rr = np.repeat(rr,10000)
# @Nils Werner's soln
In [18]: %timeit np.sum(rr == 'A')
1000 loops, best of 3: 734 µs per loop
# Approach #1 from this post
In [17]: %timeit np.count_nonzero(rr=='A')
1000 loops, best of 3: 659 µs per loop
# Approach #2 from this post
In [24]: %timeit np.count_nonzero(rr.view(np.uint8)==ord('A'))
10000 loops, best of 3: 40.2 µs per loop