Efficiently replace elements in array based on dictionary - NumPy / Python

前端 未结 4 1149
梦谈多话
梦谈多话 2020-12-10 05:22

First, of all, my apologies if this has been answered elsewhere. All I could find were questions about replacing elements of a given value, not elements of multiple values.<

4条回答
  •  南方客
    南方客 (楼主)
    2020-12-10 06:15

    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]
    

提交回复
热议问题