Search code examples
numpydictionaryhashable

how to use NumPy array as a key in dict - Python


I would like to use NumPy arrays as keys where each key will have a set of NumPy arrays as a value. I am wondering what is the most efficient way of doing this operation (i..e, inserting, searching).

my_keys = np.random.rand(5, 2)
my_keys 
array([[0.05152605, 0.12405425],
       [0.44344738, 0.87479441],
       [0.39542315, 0.2788064 ],
       [0.470308  , 0.73640885],
       [0.58107681, 0.42968256]])
my_values =  np.random.rand(10, 2)
my_values 
array([[0.96544233, 0.38396357],
       [0.55453457, 0.83432399],
       [0.8736443 , 0.0506048 ],
       [0.98617731, 0.41264541],
       [0.76856053, 0.23441502],
       [0.06770689, 0.27087991],
       [0.29328327, 0.57327051],
       [0.31798657, 0.11341894],
       [0.76256025, 0.08786568],
       [0.71370639, 0.30637008]])

Suppose my first key is [0.05152605, 0.12405425], I want the first two rows of my_values to be the value as [[0.96544233, 0.38396357],[0.55453457, 0.83432399]]

There is a post here for a similar question, but there is no code snippet. For example, I've tried what is offered as

my_array = numpy.arange(4).reshape((2,2))
my_dict = {}
my_dict[my_array.tobytes()] = None

however, it did not work for me.


Solution

  • You can zip the keys and a reshaped view of your values, then construct a dict by hashing the keys:

    >>> d = {k.tobytes(): v for k, v in zip(my_keys, my_values.reshape(5,2,2))}
    {b'\x0f4U\xe6\x9cN\xd9?v\x97z\xcc\xf6\xd7\xd1?': 
         array([[0.76856053, 0.23441502], [0.06770689, 0.27087991]]),
     b'1\xbcHW\x9fa\xaa?\xe6\x07\xae\xf2\x04\xc2\xbf?': 
         array([[0.96544233, 0.38396357], [0.55453457, 0.83432399]]),
     b'[3\xa6\x1eqa\xdc?B\x8e\xb5\xd8P\xfe\xeb?': 
         array([[0.8736443 , 0.0506048 ], [0.98617731, 0.41264541]]),
     b'\x89?\xedd.\x98\xe2?\xc3#\xb7G\xeb\x7f\xdb?': 
         array([[0.76256025, 0.08786568], [0.71370639, 0.30637008]]),
     b'\xcd\x04\xc3\xb9\x86\x19\xde?\xdf\x84\xe7J\xa9\x90\xe7?': 
         array([[0.29328327, 0.57327051], [0.31798657, 0.11341894]])}
    

    Then, given a key k, you can query the dictionnary:

    >>> k = my_keys[2]
    >>> d[k.tobytes()]
    array([[0.76856053, 0.23441502],
           [0.06770689, 0.27087991]])