Вот пример, основанный на view
+ lookup
-
def map_indices_conststring(a, b):
a2D = a.view(np.uint8)[::4].reshape(len(a),-1)
b2D = b.view(np.uint8)[::4].reshape(len(b),-1)
n = b2D.shape[1]
lookup = np.zeros(256, dtype=bool)
mask = np.ones(len(a), dtype=bool)
for i in range(n):
lookup[b2D[:,i]] = 1
mask &= lookup[a2D[:,i]]
out = np.flatnonzero(mask)
return out
Пробный прогон -
In [46]: a
Out[46]:
array(['a123', 'b232', 'c434', 'b235', 'a123', 'd223', 'b232'],
dtype='<U4')
In [47]: b
Out[47]: array(['a123', 'b232'], dtype='<U4')
In [48]: map_indices_conststring(a, b)
Out[48]: array([0, 1, 4, 6])
Время для строковых данных с 1.5M
неуникальным и 15K
строковые массивы уникального размера -
In [2]: a = np.random.randint(10000000000,99999999999,(1500000)).astype(str)
In [3]: b = np.unique(np.random.randint(10000000000,99999999999,(15000)).astype(str))
In [4]: %timeit map_indices_conststring(a, b)
266 ms ± 2.63 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# @yatu's soln
In [5]: %timeit np.flatnonzero(np.isin(a,b))
1.03 s ± 3.75 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)