Approach #1 : Loopy one with array data
One approach would be extracting the keys and values in arrays and then use a similar loop –
k = np.array(list(mapping.keys()))
v = np.array(list(mapping.values()))
out = np.zeros_like(input_array)
for key,val in zip(k,v):
out[input_array==key] = val
Benefit with this one over the original one is the spatial-locality of the array data for efficient data-fetching, which is used in the iterations.
Also, since you mentioned thousand large np.arrays
. So, if the mapping
dictionary stays the same, that step to get the array versions – k
and v
would be a one-time setup process.
Approach #2 : Vectorized one with searchsorted
A vectorized one could be suggested using np.searchsorted
–
sidx = k.argsort() #k,v from approach #1
k = k[sidx]
v = v[sidx]
idx = np.searchsorted(k,input_array.ravel()).reshape(input_array.shape)
idx[idx==len(k)] = 0
mask = k[idx] == input_array
out = np.where(mask, v[idx], 0)
Approach #3 : Vectorized one with mapping-array for integer keys
A vectorized one could be suggested using a mapping array for integer keys, which when indexed by the input array would lead us directly to the final output –
mapping_ar = np.zeros(k.max()+1,dtype=v.dtype) #k,v from approach #1
mapping_ar[k] = v
out = mapping_ar[input_array]