0

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])
3
  • Can you specify he expected shape of graph_struct? Please provide some example of input and expected output. Commented Nov 6, 2019 at 9:35
  • Can you use a list? Why array? What shape and dtype do you need? Commented Nov 6, 2019 at 11:30
  • With that mix of shapes trying to construct an object dtype array with np.array raises an error.. There are ways around it, but ... Commented Nov 6, 2019 at 12:12

2 Answers 2

1

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

13 Comments

I tried graph_struct = np.array([(adjacency_matrix),(Node_labels),(Adj_joint_array)],dtype='(4,4)i,(4,1)i,(4,3)i'). It throws the error: ValueError: could not broadcast input array from shape (4,4) into shape (4)
replace [] with ()
Good answers should have a working example. Otherwise they arely to be buggy.
@hpaulj, I would like to add a working example but no reasonable input is provided by the author of the question. I am not even sure if types of individual arrays are correct. Anyway, I will provide some example
@Ben, I've updated the answer to provide a more robust way to construct the dtype
|
0
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.

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.