1

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.

3
  • What's the point to doing this, especially if the arrays are float? Even if you succeed in converting the array to something hashable, generating that 'key' again from scratch may be difficult. Usually we recommend using np.isclose (or allclose) when comparing float arrays, due to the inherent precision limits of floats. Even if 2 arrays are allclose, they could produce different tobytes strings and dict keys. Commented Sep 4, 2021 at 19:56
  • Could you share a small code snippet showing what you recommend? I was also asking what could be the most efficient way to do this operation. I have vectors of floats each of which is associated with several arrays. I thought that using dict would be the way to go. Commented Sep 5, 2021 at 14:19
  • I can't suggest an alternative without knowing something about this "association". What's the source of these arrays (keys and values). How will you create/choose keys after you've create the dict. It's one thing to write adict['foobar'], quite another to use adict[list(adict.keys)[3]] to access the array corresponding to the 4th key vector. Commented Sep 6, 2021 at 6:56

1 Answer 1

2

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]])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.