 # Convert VertexCluster to 2d Numpy array

Given a `communities` extracted using VertexClustering as below

`partition_all = ig.VertexClustering(G, partitions.membership)`
I using the following line to convert it into numpy

``````membership_arr=np.array(partition_all.membership).reshape(3,-1).transpose()
label_arr=np.array([f'{v["name"]}-{v["slice"]}' for v in G.vs]).reshape(3,-1).transpose()
``````

However, the above solution only work if all node are present across slices and will throw an error if some nodes are missing,

`ValueError: cannot reshape array of size 20 into shape (3,newaxis)`

Hence, I wonder whether there is build-in function to cater transformation to numpy array?

The full code to reproduce the above error

``````import leidenalg as la
import igraph as ig
import numpy as np

# Create first slice graph
G1 = ig.Graph.Formula('A-B-D-C-A, D-E-G-F-D')

# Make a copy, remove edge between C and F

# Make a copy, remove vertex A
G3 = G1.copy();G3.delete_vertices('A')

# Convert from slices to layers
G_layers, G_interslice, G = la.time_slices_to_layers([G1, G2, G3], interslice_weight=1e-1,
slice_attr='slice', vertex_id_attr='name',
edge_type_attr='type', weight_attr='weight' )

# Create partitions
gamma = 0.3
partitions = [la.CPMVertexPartition(H, node_sizes='node_size',weights='weight',
resolution_parameter=gamma) for H in G_layers]
interslice_partition = la.CPMVertexPartition(G_interslice, resolution_parameter=0,
node_sizes='node_size', weights='weight')

# Detect communities
optimiser = la.Optimiser()
optimiser.set_rng_seed(11)
diff = optimiser.optimise_partition_multiplex(partitions + [interslice_partition])

partition_all = ig.VertexClustering(G, partitions.membership)
membership_arr=np.array(partition_all.membership).reshape(3,-1).transpose()
label_arr=np.array([f'{v["name"]}-{v["slice"]}' for v in G.vs]).reshape(3,-1).transpose()
# G3.delete_vertices('A')
``````

It might be most useful to convert the results first in an easy to use representation. The following code transforms the membership into a dict-of-dicts, representing the membership of each node in each slice:

``````# Get results for each slice separately
membership_slice = {}
for v, m in zip(G.vs, partitions.membership):
if v['slice'] not in membership_slice:
membership_slice[v['slice']] = {}
membership_slice[v['slice']][v['name']] = m
``````

This produces something like

``````{0: {'A': 1, 'B': 1, 'D': 0, 'C': 1, 'E': 0, 'G': 0, 'F': 0},
1: {'A': 1, 'B': 1, 'D': 0, 'C': 0, 'E': 0, 'G': 0, 'F': 0},
2: {'B': 0, 'D': 0, 'C': 0, 'E': 2, 'G': 2, 'F': 2}}
``````

Note that indeed the second slice does not have a node `A`. This is something that is expected, graphs across different slices do not all necessarily need to have all nodes present. It is then most convenient to convert it to a `pandas` dataframe, using

``````membership_df = pd.DataFrame(membership_slice)
``````

We now have a `pandas` `DataFrame` that looks like

``````   0  1    2
A  1  1  NaN
B  1  1  0.0
D  0  0  0.0
C  1  0  0.0
E  0  0  2.0
G  0  0  2.0
F  0  0  2.0
``````

Here, node `A` for slice `2` is missing, indicated by `NaN` (not a number). Notice that the membership for slice 2 is now a `float` instead of an `int`, because an `int` cannot represent `NaN`.

If you really need a `numpy` representation of this, you can simply get that by using `membership_df.values`.

Thanks for the suggestion, presenting the membership as proposed above remove ambiguity about the node membership.

The graph (with missing node A) used in this discussion is not ideal for the flexibility calculation. This metric is usually used in neuro-image research, and rarely there are missing node (brain region/node).