Property queries
As you will have seen in the ingestion tutorial, graphs, nodes and edges may all have constant
and temporal
properties, consisting of a wide range of data types. Raphtory provides a unified API for accessing this data via the Properties object available on all classes by calling .properties
.
This Properties
class offers several functions for you to access the values you are interested in in the most appropriate format. To demonstrate this let's create a simple graph with one node that has a variety of different properties, both temporal and constant.
We can grab this nodes property object and call all of the functions to access the data:
keys()
: Returns all of the property keys (names).values()
: Returns the latest value for each property.items()
: Combines thekeys()
andvalues()
into a list of tuples.get()
: Returns the latest value for a given key if the property exists orNone
if it does not.as_dict()
: Converts theProperties
object into a standard python dictionary.
from raphtory import Graph
property_g = Graph()
# Create the node and add a variety of temporal properties
v = property_g.add_node(
timestamp=1,
id="User",
properties={"count": 1, "greeting": "hi", "encrypted": True},
)
property_g.add_node(
timestamp=2,
id="User",
properties={"count": 2, "balance": 0.6, "encrypted": False},
)
property_g.add_node(
timestamp=3,
id="User",
properties={"balance": 0.9, "greeting": "hello", "encrypted": True},
)
# Add some constant properties
v.add_constant_properties(
properties={
"inner data": {"name": "bob", "value list": [1, 2, 3]},
"favourite greetings": ["hi", "hello", "howdy"],
},
)
# Call all of the functions on the properties object
properties = v.properties
print("Property keys:", properties.keys())
print("Property values:", properties.values())
print("Property tuples:", properties.items())
print("Latest value of balance:", properties.get("balance"))
print("Property keys:", properties.as_dict(), "\n")
# Access the keys of the constant and temporal properties individually
constant_properties = properties.constant
temporal_properties = properties.temporal
print("Constant property keys:", constant_properties.keys())
print("Constant property keys:", temporal_properties.keys())
Output
Property keys: ['count', 'greeting', 'encrypted', 'balance', 'inner data', 'favourite greetings']
Property values: [2]
Property tuples: [('count', 2), ('greeting', 'hello'), ('encrypted', True), ('balance', 0.9), ('inner data', {'value list': [1, 2, 3], 'name': 'bob'}), ('favourite greetings', ['hi', 'hello', 'howdy'])]
Latest value of balance: 0.9
Property keys: {'inner data': {'value list': [1, 2, 3], 'name': 'bob'}, 'greeting': 'hello', 'favourite greetings': ['hi', 'hello', 'howdy'], 'balance': 0.9, 'encrypted': True, 'count': 2}
Constant property keys: ['inner data', 'favourite greetings']
Constant property keys: ['count', 'greeting', 'encrypted', 'balance']
The Properties
class also has two attributes constant
and temporal
which have all of the above functions, but are restricted to only the properties which fall within their respective catagories.
Info
The semantics for ConstProperties are exactly the same as described above. TemporalProperties on the other hand allow you to do much more, as is discussed below.
Temporal specific functions
As temporal properties have a history, we may often want to do more than just look at the latest value. As such, calling get()
, values()
or items()
on TemporalProperties
will return a TemporalProp object which contains all of the value history.
TemporalProp
has a host of helper functions covering anything that you may want to do with this history. This includes:
value()
/values()
: Get the latest value or all values of the property.at()
: Get the latest value of the property at the specified time.history()
/history_date_time()
: Get the timestamps of all updates to the property.items()
/items_date_time()
: Mergesvalues()
andhistory()
/history_date_time()
into a list of tuples.mean()
/median()
/average()
: If the property is orderable, get the average value for the property.min()
/max()
: If the property is orderable, get the minimum or maximum value.count()
: Get the number of updates which have occurredsum()
: If the property is additive, sum the values and return the result.
In the code below, we call a subset of these functions on the Weight
property of the edge between FELIPE
and MAKO
in our monkey graph.
properties = g.edge("FELIPE", "MAKO").properties.temporal
print("Property keys:", properties.keys())
weight_prop = properties.get("Weight")
print("Weight property history:", weight_prop.items())
print("Average interaction weight:", weight_prop.mean())
print("Total interactions:", weight_prop.count())
print("Total interaction weight:", weight_prop.sum())
Output
Property keys: ['Weight']
Weight property history: [(1560437400000, 1), (1560437640000, 1), (1560935460000, 1), (1561043280000, 0), (1561043280000, 1), (1561043340000, 1), (1561117620000, 1), (1561373880000, 1), (1561373880000, 1), (1561373940000, 1), (1561373940000, 0), (1561373940000, 1), (1561373940000, 1), (1561373940000, 1), (1561390860000, 1), (1561390860000, 1), (1561390860000, 1), (1561390920000, 1), (1561643580000, 1), (1561717080000, 1), (1561717140000, 1), (1561970760000, 1), (1562148960000, 1), (1562148960000, 1), (1562149020000, 1), (1562149020000, 1), (1562149080000, 1), (1562671020000, 1)]
Average interaction weight: 0.9285714285714286
Total interactions: 28
Total interaction weight: 26