У меня машина медленная, поэтому результаты по абсолютному времени могут различаться:
 import random
import numpy as np
def create_text(length):
    alphabet = {str(i-1): np.float64(i / 55.0) for i in range(1, 11)}
    return np.random.choice(list(alphabet.keys()), p=list(alphabet.values()), size=length)
text = create_text(100000000)
text, len(text)
(array(, 
       dtype='<U1'), 100000000)
 def f_prev(text):
    l1 = np.unique(text, return_counts=True)
    l2 = zip(*l1)
    l3 = {code: count for code, count in l2}
    return l3
 def f_view(text):
    l1 = np.unique(text.view(np.int), return_counts=True)
    l2 = zip(*l1)
    l3 = {chr(code): count for code, count in l2}
    return l3
{'0': 1820740,
 ‘1’: 3636051,
 ‘2’: 5458589,
 ‘3’: 7271355,
 ‘4’: 9086383,
 ‘5’: 10906851,
 ‘6’: 12728655,
 ‘7’: 14542164,
 ‘8’: 16360778,
 ‘9’: 18188434}
 f_prev(text) == f_view(text)
True
 %%timeit -n 5
f_prev(text)
5 loops, best of 3: 21.3 s per loop
 %%timeit -n 5
f_view(text)
5 loops, best of 3: 8.16 s per loop
PS: чуть позже может через сифон другой вариант попробую, но нет уверенности что будет много быстрее