Attributes & views¶
Two related concepts:
- Attributes are arbitrary metadata on vertices, edges, slices, or the graph as a whole.
- Views are read-only dataframes that join structure with attributes so you can filter, group, and inspect.
All attribute setters have a _bulk variant for batched writes.
In [1]:
Copied!
from annnet import AnnNet
G = AnnNet(directed=True)
G.add_vertices(['A', 'B', 'C', 'D'])
G.add_edges('A', 'B', edge_id='e1', weight=1.0)
G.add_edges('B', 'C', edge_id='e2', weight=2.0)
G.add_edges('C', 'D', edge_id='e3', weight=1.5)
G
from annnet import AnnNet
G = AnnNet(directed=True)
G.add_vertices(['A', 'B', 'C', 'D'])
G.add_edges('A', 'B', edge_id='e1', weight=1.0)
G.add_edges('B', 'C', edge_id='e2', weight=2.0)
G.add_edges('C', 'D', edge_id='e3', weight=1.5)
G
Out[1]:
AnnNet object with n_vertices × n_edges = 4 × 3
directed: True
slices: ['default']
Vertex attributes¶
G.attrs.set_vertex_attrs(vertex_id, **attrs) writes one row;
G.attrs.set_vertex_attrs_bulk({vid: {...}, ...}) writes many in one call.
In [2]:
Copied!
G.attrs.set_vertex_attrs('A', tier=1, label='alpha')
G.attrs.set_vertex_attrs_bulk(
{
'B': {'tier': 1, 'label': 'beta'},
'C': {'tier': 2, 'label': 'gamma'},
'D': {'tier': 2, 'label': 'delta'},
}
)
print(G.attrs.get_vertex_attrs('A'))
print(G.attrs.get_attr_vertex('B', 'label'))
G.attrs.set_vertex_attrs('A', tier=1, label='alpha')
G.attrs.set_vertex_attrs_bulk(
{
'B': {'tier': 1, 'label': 'beta'},
'C': {'tier': 2, 'label': 'gamma'},
'D': {'tier': 2, 'label': 'delta'},
}
)
print(G.attrs.get_vertex_attrs('A'))
print(G.attrs.get_attr_vertex('B', 'label'))
{'tier': 1, 'label': 'alpha'}
beta
Edge attributes¶
Same shape as vertex attributes, keyed by edge_id.
In [3]:
Copied!
G.attrs.set_edge_attrs_bulk(
{
'e1': {'confidence': 0.9, 'interaction': 'activation'},
'e2': {'confidence': 0.7, 'interaction': 'inhibition'},
'e3': {'confidence': 0.95, 'interaction': 'activation'},
}
)
# Filter by attribute value
activations = G.attrs.get_edges_by_attr('interaction', 'activation')
print('activation edges:', activations)
G.attrs.set_edge_attrs_bulk(
{
'e1': {'confidence': 0.9, 'interaction': 'activation'},
'e2': {'confidence': 0.7, 'interaction': 'inhibition'},
'e3': {'confidence': 0.95, 'interaction': 'activation'},
}
)
# Filter by attribute value
activations = G.attrs.get_edges_by_attr('interaction', 'activation')
print('activation edges:', activations)
activation edges: ['e1', 'e3']
!!! note "Reserved keys"
A handful of attribute names are structural (e.g. vertex_id,
source, target, weight, directed, slice, kind,
members, head, tail). Passing them as attrs raises
ValueError — pick a different key.
In [4]:
Copied!
try:
G.attrs.set_edge_attrs('e1', source='X')
except ValueError as e:
print('caught:', e)
try:
G.attrs.set_edge_attrs('e1', source='X')
except ValueError as e:
print('caught:', e)
caught: edge attributes use reserved key(s): ['source']. These names are part of the structural / dispatch contract; rename your attribute(s) to use a different key.
Graph-level attributes (uns)¶
For dataset / study metadata that lives on the graph itself, use the
anndata-style uns dict.
In [5]:
Copied!
G.uns['study'] = 'demo'
G.uns['organism'] = 'Homo sapiens'
print(G.attrs.get_graph_attributes())
G.uns['study'] = 'demo'
G.uns['organism'] = 'Homo sapiens'
print(G.attrs.get_graph_attributes())
{'study': 'demo', 'organism': 'Homo sapiens'}
Views¶
G.views.* returns read-only dataframes. The columns are the structural
columns (source, target, weight, …) plus all attribute keys.
In [6]:
Copied!
G.views.edges().head()
G.views.edges().head()
Out[6]:
shape: (3, 13)
| edge_id | kind | source | target | edge_type | head | tail | members | directed | global_weight | confidence | interaction | effective_weight |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| str | str | str | str | str | null | null | null | bool | f64 | f64 | str | f64 |
| "e1" | "binary" | "A" | "B" | "binary" | null | null | null | true | 1.0 | 0.9 | "activation" | 1.0 |
| "e2" | "binary" | "B" | "C" | "binary" | null | null | null | true | 2.0 | 0.7 | "inhibition" | 2.0 |
| "e3" | "binary" | "C" | "D" | "binary" | null | null | null | true | 1.5 | 0.95 | "activation" | 1.5 |
In [7]:
Copied!
G.views.vertices().head()
G.views.vertices().head()
Out[7]:
shape: (4, 3)
| vertex_id | tier | label |
|---|---|---|
| str | i64 | str |
| "A" | 1 | "alpha" |
| "B" | 1 | "beta" |
| "C" | 2 | "gamma" |
| "D" | 2 | "delta" |
Next: 03 — IO & interop.