Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting dictionary with known indices to a multidimensional array

I have a dictionary with entries labelled as {(k,i): value, ...}. I now want to convert this dictionary into a 2d array where the value given for an element of the array at position [k,i] is the value from the dictionary with label (k,i). The length of the rows will not necessarily be of the same size (e.g. row k = 4 may go up to index i = 60 while row k = 24 may go up to index i = 31). Due to the asymmetry, it is fine to make all additional entries in a particular row equal to 0 in order to have a rectangular matrix.

like image 754
Mathews24 Avatar asked Aug 02 '16 20:08

Mathews24


People also ask

Does Numpy work on dictionary?

It's sometimes required to convert a dictionary in Python into a NumPy array and Python provides an efficient method to perform this operation. Converting a dictionary to NumPy array results in an array holding the key-value pairs of the dictionary. Let's see the different methods: Method 1: Using numpy.

Can we store dictionary in Numpy array?

We can use Python's numpy. save() function from transforming an array into a binary file when saving it. This method also can be used to store the dictionary in Python.

Is dictionary in Python indexable?

Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys.


1 Answers

Here's an approach -

# Get keys (as indices for output) and values as arrays
idx = np.array(d.keys())
vals = np.array(d.values())

# Get dimensions of output array based on max extents of indices
dims = idx.max(0)+1

# Setup output array and assign values into it indexed by those indices
out = np.zeros(dims,dtype=vals.dtype)
out[idx[:,0],idx[:,1]] = vals

We could also use sparse matrices to get the final output. e.g. with coordinate format sparse matrices. This would be memory efficient when kept as sparse matrices. So, the last step could be replaced by something like this -

from scipy.sparse import coo_matrix

out = coo_matrix((vals, (idx[:,0], idx[:,1])), dims).toarray()

Sample run -

In [70]: d
Out[70]: {(1, 4): 120, (2, 2): 72, (2, 3): 100, (5, 2): 88}

In [71]: out
Out[71]: 
array([[  0,   0,   0,   0,   0],
       [  0,   0,   0,   0, 120],
       [  0,   0,  72, 100,   0],
       [  0,   0,   0,   0,   0],
       [  0,   0,   0,   0,   0],
       [  0,   0,  88,   0,   0]])

To make it generic for ndarrays of any number of dimensions, we can use linear-indexing and use np.put to assign values into the output array. Thus, in our first approach, just replace the last step of assigning values with something like this -

np.put(out,np.ravel_multi_index(idx.T,dims),vals)

Sample run -

In [106]: d
Out[106]: {(1,0,0): 99, (1,0,4): 120, (2,0,2): 72, (2,1,3): 100, (3,0,2): 88}

In [107]: out
Out[107]: 
array([[[  0,   0,   0,   0,   0],
        [  0,   0,   0,   0,   0]],

       [[ 99,   0,   0,   0, 120],
        [  0,   0,   0,   0,   0]],

       [[  0,   0,  72,   0,   0],
        [  0,   0,   0, 100,   0]],

       [[  0,   0,  88,   0,   0],
        [  0,   0,   0,   0,   0]]])
like image 152
Divakar Avatar answered Oct 02 '22 18:10

Divakar