# Convert VertexCluster to 2d Numpy array

**URL:** <https://igraph.discourse.group/t/convert-vertexcluster-to-2d-numpy-array/861>\
**Category:** Usage\
**Tags:** Python\
**Created:** [13 September 2021 13:32 UTC](https://igraph.discourse.group/t/convert-vertexcluster-to-2d-numpy-array/861 "2021-09-13T13:32:46Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![balandongiv](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/balandongiv/32/553_2.png) [@balandongiv](https://igraph.discourse.group/u/balandongiv)\
**Post date:** [13 September 2021 13:32 UTC](https://igraph.discourse.group/t/convert-vertexcluster-to-2d-numpy-array/861/1 "2021-09-13T13:32:46Z")

</div>

Given a `communities` extracted using VertexClustering as below

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

```auto
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

```auto
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
G2 = G1.copy(); G2.add_edge('C', '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[0].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')

```

---

<div class="post-metadata">

**Author:** ![vtraag](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/vtraag/32/38_2.png) [@vtraag](https://igraph.discourse.group/u/vtraag)\
**Post date:** [16 September 2021 07:21 UTC](https://igraph.discourse.group/t/convert-vertexcluster-to-2d-numpy-array/861/2 "2021-09-16T07:21:09Z")

</div>

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:

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

```

This produces something like

```python
{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

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

```

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

```python
   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`.

---

<div class="post-metadata">

**Author:** ![balandongiv](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/balandongiv/32/553_2.png) [@balandongiv](https://igraph.discourse.group/u/balandongiv)\
**Post date:** [16 September 2021 12:51 UTC](https://igraph.discourse.group/t/convert-vertexcluster-to-2d-numpy-array/861/3 "2021-09-16T12:51:45Z")

</div>

> [@vtraag](#):
>
> 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:

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

> [@vtraag](#):
>
> 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` .

The graph (with missing node A) used in this discussion is not ideal for the [flexibility calculation](https://igraph.discourse.group/t/how-to-quantify-time-dependent-network-flexibility-in-igraph/843/7). This metric is usually used in neuro-image research, and rarely there are missing node (brain region/node).
