Ben
Ben

Reputation: 57

How to get array of different dimensional multiple arrays in python?

I am constructing graph data. Therefore I generated 3 different matrix like adjacency_matrix, Node_labels, & Adj_joint_matrix.

adjacency_matrix.shape = (4,4)
Node_labels.shape = (4,1)
Adj_joint_matrix.shape = (4,3)

At that time, I want to merge these three multidimensional arrays into one common array called graph_struct. I tried

graph_struct = np.asarray([adjacency_matrix],[Node_labels],[Adj_joint_matrix]) 
graph_struct = np.array([adjacency_matrix],[Node_labels],[Adj_joint_matrix]).

But it doesn't give the solution.

output should like:

graph_struct = array([adjacency_matrix],[Node_labels],[Adj_joint_matrix])

Upvotes: 0

Views: 356

Answers (2)

hpaulj
hpaulj

Reputation: 231395

In [268]: x = np.ones((4,3),int); y = np.zeros((4,1),int)                       

With this combination of shapes (same 1st dimension) np.array raises an error:

In [269]: np.array((x,y))                                                       
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-269-8419f5dd7aa8> in <module>
----> 1 np.array((x,y))

ValueError: could not broadcast input array from shape (4,3) into shape (4)

WIth different 1st dimensions, it makes an object dtype array - basically a glorified (or debased) list of arrays:

In [270]: np.array((x.T,y.T))                                                   
Out[270]: 
array([array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]]),
       array([[0, 0, 0, 0]])], dtype=object)

np.array tries to make a regular multidimensional array. If the shapes don't allow that, it has to fall back on the object dtype, or fail.

We can pre allocate the object array, and assign the elements:

In [271]: res = np.empty((2,),object)                                           
In [272]: res                                                                   
Out[272]: array([None, None], dtype=object)
In [273]: res[0]=x; res[1] = y                                                  
In [274]: res                                                                   
Out[274]: 
array([array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]]),
       array([[0],
       [0],
       [0],
       [0]])], dtype=object)

A potentially useful structured array can be constructed with:

In [278]: res1 = np.zeros((4,), dtype=[('x',int,(3,)),('y',int,(1,))])          
In [279]: res1                                                                  
Out[279]: 
array([([0, 0, 0], [0]), ([0, 0, 0], [0]), ([0, 0, 0], [0]),
       ([0, 0, 0], [0])], dtype=[('x', '<i8', (3,)), ('y', '<i8', (1,))])
In [280]: res1['x']=x                                                           
In [281]: res1['y']=y                                                           
In [282]: res1                                                                  
Out[282]: 
array([([1, 1, 1], [0]), ([1, 1, 1], [0]), ([1, 1, 1], [0]),
       ([1, 1, 1], [0])], dtype=[('x', '<i8', (3,)), ('y', '<i8', (1,))])
In [283]: res1[0]                                                               
Out[283]: ([1, 1, 1], [0])

If the size 4 dimension is put in the dtype, the result is a 0d array:

In [284]: np.array((x,y), dtype=[('x',int,(4,3)),('y',int,(4,1))])              
Out[284]: 
array(([[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]], [[0], [0], [0], [0]]),
      dtype=[('x', '<i8', (4, 3)), ('y', '<i8', (4, 1))])
In [285]: res2 = np.array((x,y), dtype=[('x',int,(4,3)),('y',int,(4,1))])       
In [287]: res2.shape                                                            
Out[287]: ()

Practically this is more like a dictionary, {'x':x, 'y':y} than an array.

Upvotes: 0

tstanisl
tstanisl

Reputation: 14127

You could use structured arrays. See https://docs.scipy.org/doc/numpy/user/basics.rec.html#.

I assume that type of adjacency_matrix is bool. The other two are ints. You can create a structured array with command:

graph_struct = np.array((adjacency_matrix,Node_labels,Adj_joint_matrix),
                        dtype='(4,4)?,(4,1)i,(4,3)i')

Remember to put () around structure elements to prevent numpy trying to merge elements to a single ndarray.

For inputs:

adjacency_matrix = np.array([[0,1,0,0],[1,0,1,1],[0,1,0,0],[0,1,0,0]], dtype=bool)
Node_labels = np.array([[1],[2],[3],[4]], dtype=int)
Adj_joint_matrix = np.arange(12).reshape(4,3)

The output is a structured array with fields f0, f1, f2:

array(([[False,  True, False, False], [ True, False,  True,  True], [False,  True, False, False], [False,  True, False, False]],
       [[1], [2], [3], [4]],
       [[ 0,  1,  2], [ 3,  4,  5], [ 6,  7,  8], [ 9, 10, 11]]),
       dtype=[('f0', '?', (4, 4)), ('f1', '<i4', (4, 1)), ('f2', '<i4', (4, 3))])

If the shape of your arrays is not known in advance then it can be constructed with:

graph_struct_dtype = np.dtype([('f0',(bool, adjacency_matrix.shape)),
                               ('f1',(int, Node_labels.shape)),
                               ('f2',(int, Adj_joint_matrix.shape))])

graph_struct = np.array((adjacency_matrix,Node_labels,Adj_joint_matrix),
                        dtype=graph_struct_dtype)

Upvotes: 1

Related Questions