turicreate.SGraph.triple_apply¶
-
SGraph.triple_apply(triple_apply_fn, mutated_fields, input_fields=None)¶ Apply a transform function to each edge and its associated source and target vertices in parallel. Each edge is visited once and in parallel. Modification to vertex data is protected by lock. The effect on the returned SGraph is equivalent to the following pseudocode:
>>> PARALLEL FOR (source, edge, target) AS triple in G: ... LOCK (triple.source, triple.target) ... (source, edge, target) = triple_apply_fn(triple) ... UNLOCK (triple.source, triple.target) ... END PARALLEL FOR
Parameters: - triple_apply_fn : function
The function to apply to each triple of (source_vertex, edge, target_vertex). This function must take as input a tuple of (source_data, edge_data, target_data) and return a tuple of (new_source_data, new_edge_data, new_target_data). All variables in the both tuples must be of dict type. This can also be a toolkit extension function which is compiled as a native shared library using SDK.
- mutated_fields : list[str] | str
Fields that
triple_apply_fnwill mutate. Note: columns that are actually mutated by the triple apply function but not specified inmutated_fieldswill have undetermined effects.- input_fields : list[str] | str, optional
Fields that
triple_apply_fnwill have access to. The default isNone, which grants access to all fields.mutated_fieldswill always be included ininput_fields.
Returns: - out : SGraph
A new SGraph with updated vertex and edge data. Only fields specified in the
mutated_fieldsparameter are updated.
Notes
triple_applydoes not currently support creating new fields in the lambda function.
Examples
Import turicreate and set up the graph.
>>> edges = turicreate.SFrame({'source': range(9), 'dest': range(1, 10)}) >>> g = turicreate.SGraph() >>> g = g.add_edges(edges, src_field='source', dst_field='dest') >>> g.vertices['degree'] = 0
Define the function to apply to each (source_node, edge, target_node) triple.
>>> def degree_count_fn (src, edge, dst): src['degree'] += 1 dst['degree'] += 1 return (src, edge, dst)
Apply the function to the SGraph.
>>> g = g.triple_apply(degree_count_fn, mutated_fields=['degree'])
Using native toolkit extension function:
#include <model_server/lib/toolkit_function_macros.hpp> #include <vector> using namespace turi; std::vector<variant_type> connected_components_parameterized( std::map<std::string, flexible_type>& src, std::map<std::string, flexible_type>& edge, std::map<std::string, flexible_type>& dst, std::string column) { if (src[column] < dst[column]) dst[column] = src[column]; else src[column] = dst[column]; return {to_variant(src), to_variant(edge), to_variant(dst)}; } BEGIN_FUNCTION_REGISTRATION REGISTER_FUNCTION(connected_components_parameterized, "src", "edge", "dst", "column"); END_FUNCTION_REGISTRATION
compiled into example.so
>>> from example import connected_components_parameterized as cc >>> e = tc.SFrame({'__src_id':[1,2,3,4,5], '__dst_id':[3,1,2,5,4]}) >>> g = tc.SGraph().add_edges(e) >>> g.vertices['cid'] = g.vertices['__id'] >>> for i in range(2): ... g = g.triple_apply(lambda src, edge, dst: cc(src, edge, dst, 'cid'), ['cid'], ['cid']) >>> g.vertices['cid'] dtype: int Rows: 5 [4, 1, 1, 1, 4]