MikeB2019x
MikeB2019x

Reputation: 1161

graph-tool: edge property cannot be set to type 'object'

I have worked with networkx and am trying graph-tool for potentially better performance. Working through the documentation I wish to create edges with properties. In networkx I can do something like this for some graph G:

G.add_edge(vertex_1, vertex_2, attr_dict={python dict of 'property: value'})

I wanted to do the same in graph-tool. From the docs I tried the example with a slight change in that one of the properties in a python dict instead of an int:

edge_list = [(0, 1, .3, {'name':'hello'}), (2, 3, .1,  {'name':'good'}), (2, 0, .4,  {'name':'by'})]
g = gt.Graph()
eweight = g.new_ep("double")
elayer = g.new_ep("object")
g.add_edge_list(edge_list, eprops=[eweight, elayer])
print(eweight.a)
print(elayer.a)
g.get_edges()

OUTPUT:

[0.3 0.1 0.4]
None
array([[0, 1],
       [2, 3],
       [2, 0]])

I can see that the edges were entered correctly why is 'None' returned for the 'elayer' property?

UPDATE:

I have looked at the Property Map docs and the example there looks like this:

eprop_dict = g.new_edge_property("object")                # Arbitrary Python object.
e = g.edges().next()
eprop_dict[e] = {"foo": "bar", "gnu": 42}                 # In this case, a dict.

Also had a look at the source code.

Upvotes: 2

Views: 429

Answers (1)

Tiago Peixoto
Tiago Peixoto

Reputation: 5261

Let's look at what the documentation tells us:

help(elayer)

This gives us:

a
    Shortcut to the :meth:`~PropertyMap.get_array` method
    as an attribute. This makes assignments more convenient, e.g.:
        
    >>> g = gt.Graph()
    >>> g.add_vertex(10)
    <...>
    >>> prop = g.new_vertex_property("double")
    >>> prop.a = np.random.random(10)           # Assignment from array

Now let us look at the documentation of PropertyMap.get_array:

help(elayer.get_array)


get_array() method of graph_tool.EdgePropertyMap instance
    Get a :class:`numpy.ndarray` subclass (:class:`~graph_tool.PropertyArray`)
    with the property values.
    
    .. note::
    
       An array is returned *only if* the value type of the property map is
       a scalar. For vector, string or object types, ``None`` is returned
       instead. For vector and string objects, indirect array access is
       provided via the :func:`~graph_tool.PropertyMap.get_2d_array()` and
       :func:`~graph_tool.PropertyMap.set_2d_array()` member functions.

The note above answers your question: the array interface is provided only for scalar types, not arbitrary python objects.

For arbitrary types, assignment and lookup of properties is still possible using the standard interface based on edge descriptors, e.g.:

for e in g.edges():
    print(elayer[e])

which gives you

{'name': 'hello'}
{'name': 'good'}
{'name': 'by'}

Upvotes: 2

Related Questions