Base Structure Classes¶
Directed Acyclic Graph (DAG)¶

class
pgmpy.base.DAG.
DAG
(ebunch=None, latents={})[source]¶ Base class for all Directed Graphical Models.
Each node in the graph can represent either a random variable, Factor, or a cluster of random variables. Edges in the graph represent the dependencies between these.
 Parameters
data (input graph) – Data to initialize graph. If data=None (default) an empty graph is created. The data can be an edge list or any Networkx graph object.
Examples
Create an empty DAG with no nodes and no edges
>>> from pgmpy.base import DAG >>> G = DAG()
G can be grown in several ways:
Nodes:
Add one node at a time:
>>> G.add_node(node='a')
Add the nodes from any container (a list, set or tuple or the nodes from another graph).
>>> G.add_nodes_from(nodes=['a', 'b'])
Edges:
G can also be grown by adding edges.
Add one edge,
>>> G.add_edge(u='a', v='b')
a list of edges,
>>> G.add_edges_from(ebunch=[('a', 'b'), ('b', 'c')])
If some edges connect nodes not yet in the model, the nodes are added automatically. There are no errors when adding nodes or edges that already exist.
Shortcuts:
Many common graph features allow python syntax for speed reporting.
>>> 'a' in G # check if node in graph True >>> len(G) # number of nodes in graph 3

active_trail_nodes
(variables, observed=None, include_latents=False)[source]¶ Returns a dictionary with the given variables as keys and all the nodes reachable from that respective variable as values.
 Parameters
variables (str or array like) – variables whose active trails are to be found.
observed (List of nodes (optional)) – If given the active trails would be computed assuming these nodes to be observed.
include_latents (boolean (default: False)) – Whether to include the latent variables in the returned active trail nodes.
Examples
>>> from pgmpy.base import DAG >>> student = DAG() >>> student.add_nodes_from(['diff', 'intel', 'grades']) >>> student.add_edges_from([('diff', 'grades'), ('intel', 'grades')]) >>> student.active_trail_nodes('diff') {'diff': {'diff', 'grades'}} >>> student.active_trail_nodes(['diff', 'intel'], observed='grades') {'diff': {'diff', 'intel'}, 'intel': {'diff', 'intel'}}
References
Details of the algorithm can be found in ‘Probabilistic Graphical Model Principles and Techniques’  Koller and Friedman Page 75 Algorithm 3.1

add_edge
(u, v, weight=None)[source]¶ Add an edge between u and v.
The nodes u and v will be automatically added if they are not already in the graph.
 Parameters
Examples
>>> from pgmpy.base import DAG >>> G = DAG() >>> G.add_nodes_from(nodes=['Alice', 'Bob', 'Charles']) >>> G.add_edge(u='Alice', v='Bob') >>> G.nodes() NodeView(('Alice', 'Bob', 'Charles')) >>> G.edges() OutEdgeView([('Alice', 'Bob')])
When the node is not already present in the graph: >>> G.add_edge(u=’Alice’, v=’Ankur’) >>> G.nodes() NodeView((‘Alice’, ‘Ankur’, ‘Bob’, ‘Charles’)) >>> G.edges() OutEdgeView([(‘Alice’, ‘Bob’), (‘Alice’, ‘Ankur’)])
Adding edges with weight: >>> G.add_edge(‘Ankur’, ‘Maria’, weight=0.1) >>> G.edge[‘Ankur’][‘Maria’] {‘weight’: 0.1}

add_edges_from
(ebunch, weights=None)[source]¶ Add all the edges in ebunch.
If nodes referred in the ebunch are not already present, they will be automatically added. Node names can be any hashable python object.
**The behavior of adding weights is different than networkx.
 Parameters
Examples
>>> from pgmpy.base import DAG >>> G = DAG() >>> G.add_nodes_from(nodes=['Alice', 'Bob', 'Charles']) >>> G.add_edges_from(ebunch=[('Alice', 'Bob'), ('Bob', 'Charles')]) >>> G.nodes() NodeView(('Alice', 'Bob', 'Charles')) >>> G.edges() OutEdgeView([('Alice', 'Bob'), ('Bob', 'Charles')])
When the node is not already in the model: >>> G.add_edges_from(ebunch=[(‘Alice’, ‘Ankur’)]) >>> G.nodes() NodeView((‘Alice’, ‘Bob’, ‘Charles’, ‘Ankur’)) >>> G.edges() OutEdgeView([(‘Alice’, ‘Bob’), (‘Bob’, ‘Charles’), (‘Alice’, ‘Ankur’)])
Adding edges with weights: >>> G.add_edges_from([(‘Ankur’, ‘Maria’), (‘Maria’, ‘Mason’)], … weights=[0.3, 0.5]) >>> G.edge[‘Ankur’][‘Maria’] {‘weight’: 0.3} >>> G.edge[‘Maria’][‘Mason’] {‘weight’: 0.5}

add_node
(node, weight=None, latent=False)[source]¶ Adds a single node to the Graph.
 Parameters
Examples
>>> from pgmpy.base import DAG >>> G = DAG() >>> G.add_node(node='A') >>> sorted(G.nodes()) ['A']
Adding a node with some weight. >>> G.add_node(node=’B’, weight=0.3)
The weight of these nodes can be accessed as: >>> G.nodes[‘B’] {‘weight’: 0.3} >>> G.nodes[‘A’] {‘weight’: None}

add_nodes_from
(nodes, weights=None, latent=False)[source]¶ Add multiple nodes to the Graph.
**The behviour of adding weights is different than in networkx.
 Parameters
nodes (iterable container) – A container of nodes (list, dict, set, or any hashable python object).
weights (list, tuple (default=None)) – A container of weights (int, float). The weight value at index i is associated with the variable at index i.
latent (list, tuple (default=False)) – A container of boolean. The value at index i tells whether the node at index i is latent or not.
Examples
>>> from pgmpy.base import DAG >>> G = DAG() >>> G.add_nodes_from(nodes=['A', 'B', 'C']) >>> G.nodes() NodeView(('A', 'B', 'C'))
Adding nodes with weights: >>> G.add_nodes_from(nodes=[‘D’, ‘E’], weights=[0.3, 0.6]) >>> G.nodes[‘D’] {‘weight’: 0.3} >>> G.nodes[‘E’] {‘weight’: 0.6} >>> G.nodes[‘A’] {‘weight’: None}

do
(nodes, inplace=False)[source]¶ Applies the do operator to the graph and returns a new DAG with the transformed graph.
The dooperator, do(X = x) has the effect of removing all edges from the parents of X and setting X to the given value x.
 Parameters
nodes (list, arraylike) – The names of the nodes to apply the dooperator for.
inplace (boolean (default: False)) – If inplace=True, makes the changes to the current object, otherwise returns a new instance.
 Returns
pgmpy.base.DAG
 Return type
A new instance of DAG modified by the dooperator
Examples
Initialize a DAG >>> graph = DAG() >>> graph.add_edges_from([(‘X’, ‘A’), … (‘A’, ‘Y’), … (‘A’, ‘B’)]) >>> # Applying the dooperator will return a new DAG with the desired structure. >>> graph_do_A = graph.do(‘A’) >>> # Which we can verify is missing the edges we would expect. >>> graph_do_A.edges OutEdgeView([(‘A’, ‘B’), (‘A’, ‘Y’)])
References
Causality: Models, Reasoning, and Inference, Judea Pearl (2000). p.70.

get_ancestral_graph
(nodes)[source]¶ Returns the ancestral graph of the given nodes. The ancestral graph only contains the nodes which are ancestors of atleast one of the variables in node.
 Parameters
node (iterable) – List of nodes whose ancestral graph needs to be computed.
 Returns
pgmpy.base.DAG instance
 Return type
The ancestral graph.
Examples
>>> from pgmpy.base import DAG >>> dag = DAG([('A', 'C'), ('B', 'C'), ('D', 'A'), ('D', 'B')]) >>> anc_dag = dag.get_ancestral_graph(nodes=['A', 'B']) >>> anc_dag.edges() OutEdgeView([('D', 'A'), ('D', 'B')])

get_children
(node)[source]¶ Returns a list of children of node. Throws an error if the node is not present in the graph.
 Parameters
node (string, int or any hashable python object.) – The node whose children would be returned.
Examples
>>> from pgmpy.base import DAG >>> g = DAG(ebunch=[('A', 'B'), ('C', 'B'), ('B', 'D'), ('B', 'E'), ('B', 'F'), ('E', 'G')]) >>> g.get_children(node='B') ['D', 'E', 'F']

get_immoralities
()[source]¶ Finds all the immoralities in the model A vstructure X > Z < Y is an immorality if there is no direct edge between X and Y .
 Returns
set
 Return type
A set of all the immoralities in the model
Examples
>>> from pgmpy.base import DAG >>> student = DAG() >>> student.add_edges_from([('diff', 'grade'), ('intel', 'grade'), ... ('intel', 'SAT'), ('grade', 'letter')]) >>> student.get_immoralities() {('diff', 'intel')}

get_independencies
(latex=False, include_latents=False)[source]¶ Computes independencies in the DAG, by checking dseperation.
 Parameters
latex (boolean) – If latex=True then latex string of the independence assertion would be created.
include_latents (boolean) – If True, includes latent variables in the independencies. Otherwise, only generates independencies on observed variables.
Examples
>>> from pgmpy.base import DAG >>> chain = DAG([('X', 'Y'), ('Y', 'Z')]) >>> chain.get_independencies() (X ⟂ Z  Y) (Z ⟂ X  Y)

get_leaves
()[source]¶ Returns a list of leaves of the graph.
Examples
>>> from pgmpy.base import DAG >>> graph = DAG([('A', 'B'), ('B', 'C'), ('B', 'D')]) >>> graph.get_leaves() ['C', 'D']

get_markov_blanket
(node)[source]¶ Returns a markov blanket for a random variable. In the case of Bayesian Networks, the markov blanket is the set of node’s parents, its children and its children’s other parents.
 Returns
list(blanket_nodes)
 Return type
List of nodes contained in Markov Blanket
 Parameters
node (string, int or any hashable python object.) – The node whose markov blanket would be returned.
Examples
>>> from pgmpy.base import DAG >>> from pgmpy.factors.discrete import TabularCPD >>> G = DAG([('x', 'y'), ('z', 'y'), ('y', 'w'), ('y', 'v'), ('u', 'w'), ('s', 'v'), ('w', 't'), ('w', 'm'), ('v', 'n'), ('v', 'q')]) >>> G.get_markov_blanket('y') ['s', 'w', 'x', 'u', 'z', 'v']

get_parents
(node)[source]¶ Returns a list of parents of node.
Throws an error if the node is not present in the graph.
 Parameters
node (string, int or any hashable python object.) – The node whose parents would be returned.
Examples
>>> from pgmpy.base import DAG >>> G = DAG(ebunch=[('diff', 'grade'), ('intel', 'grade')]) >>> G.get_parents(node='grade') ['diff', 'intel']

static
get_random
(n_nodes=5, edge_prob=0.5, latents=False)[source]¶ Returns a randomly generated DAG with n_nodes number of nodes with edge probability being edge_prob.
 Parameters
 Returns
pgmpy.base.DAG instance
 Return type
The randomly generated DAG.
Examples
>>> from pgmpy.base import DAG >>> random_dag = DAG.get_random(n_nodes=10, edge_prob=0.3) >>> random_dag.nodes() NodeView((0, 1, 2, 3, 4, 5, 6, 7, 8, 9)) >>> random_dag.edges() OutEdgeView([(0, 6), (1, 6), (1, 7), (7, 9), (2, 5), (2, 7), (2, 8), (5, 9), (3, 7)])

get_roots
()[source]¶ Returns a list of roots of the graph.
Examples
>>> from pgmpy.base import DAG >>> graph = DAG([('A', 'B'), ('B', 'C'), ('B', 'D'), ('E', 'B')]) >>> graph.get_roots() ['A', 'E']

is_dconnected
(start, end, observed=None)[source]¶ Returns True if there is an active trail (i.e. dconnection) between start and end node given that observed is observed.
 Parameters
start (int, str, any hashable python object.) – The nodes in the DAG between which to check the dconnection/active trail.
end (int, str, any hashable python object.) – The nodes in the DAG between which to check the dconnection/active trail.
observed (list, arraylike (optional)) – If given the active trail would be computed assuming these nodes to be observed.
Examples
>>> from pgmpy.base import DAG >>> student = DAG() >>> student.add_nodes_from(['diff', 'intel', 'grades', 'letter', 'sat']) >>> student.add_edges_from([('diff', 'grades'), ('intel', 'grades'), ('grades', 'letter'), ... ('intel', 'sat')]) >>> student.is_dconnected('diff', 'intel') False >>> student.is_dconnected('grades', 'sat') True

is_iequivalent
(model)[source]¶ Checks whether the given model is Iequivalent
Two graphs G1 and G2 are said to be Iequivalent if they have same skeleton and have same set of immoralities.
Note: For same skeleton different names of nodes can work but for immoralities names of nodes must be same
 Parameters
model (A DAG object, for which you want to check Iequivalence) –
 Returns
boolean
 Return type
True if both are Iequivalent, False otherwise
Examples
>>> from pgmpy.base import DAG >>> G = DAG() >>> G.add_edges_from([('V', 'W'), ('W', 'X'), ... ('X', 'Y'), ('Z', 'Y')]) >>> G1 = DAG() >>> G1.add_edges_from([('W', 'V'), ('X', 'W'), ... ('X', 'Y'), ('Z', 'Y')]) >>> G.is_iequivalent(G1) True

local_independencies
(variables)[source]¶ Returns an instance of Independencies containing the local independencies of each of the variables.
 Parameters
variables (str or array like) – variables whose local independencies are to be found.
Examples
>>> from pgmpy.base import DAG >>> student = DAG() >>> student.add_edges_from([('diff', 'grade'), ('intel', 'grade'), >>> ('grade', 'letter'), ('intel', 'SAT')]) >>> ind = student.local_independencies('grade') >>> ind (grade ⟂ SAT  diff, intel)

moralize
()[source]¶ Removes all the immoralities in the DAG and creates a moral graph (UndirectedGraph).
A vstructure X>Z<Y is an immorality if there is no directed edge between X and Y.
Examples
>>> from pgmpy.base import DAG >>> G = DAG(ebunch=[('diff', 'grade'), ('intel', 'grade')]) >>> moral_graph = G.moralize() >>> moral_graph.edges() EdgeView([('intel', 'grade'), ('intel', 'diff'), ('grade', 'diff')])

to_daft
(node_pos=None, latex=True, pgm_params={}, edge_params={}, node_params={})[source]¶ Returns a daft (https://docs.daftpgm.org/en/latest/) object which can be rendered for publication quality plots. The returned object’s render method can be called to see the plots.
 Parameters
node_pos (str or dict (optional)) –
 If str: Must be one of the following: circular, kamada_kawai, planar, random, shell, sprint,
spectral, spiral. Please refer: https://networkx.org/documentation/stable//reference/drawing.html#modulenetworkx.drawing.layout for details on these layouts.
If dict should be of the form {node: (x coordinate, y coordinate)} describing the x and y coordinate of each node.
If no argument is provided uses random layout.
latex (boolean) – Whether to use latex for rendering the node names.
pgm_params (dict (optional)) – Any additional parameters that need to be passed to daft.PGM initializer. Should be of the form: {param_name: param_value}
edge_params (dict (optional)) – Any additional edge parameters that need to be passed to daft.add_edge method. Should be of the form: {(u1, v1): {param_name: param_value}, (u2, v2): {…} }
node_params (dict (optional)) – Any additional node parameters that need to be passed to daft.add_node method. Should be of the form: {node1: {param_name: param_value}, node2: {…} }
 Returns
daft.PGM object
 Return type
A plot of the DAG.
Examples
>>> from pgmpy.base import DAG >>> dag = DAG([('a', 'b'), ('b', 'c'), ('d', 'c')]) >>> dag.to_daft(node_pos={'a': (0, 0), 'b': (1, 0), 'c': (2, 0), 'd': (1, 1)}) <daft.PGM at 0x7fc756e936d0> >>> dag.to_daft(node_pos="circular") <daft.PGM at 0x7f9bb48c5eb0> >>> dag.to_daft(node_pos="circular", pgm_params={'observed_style': 'inner'}) <daft.PGM at 0x7f9bb48b0bb0> >>> dag.to_daft(node_pos="circular", ... edge_params={('a', 'b'): {'label': 2}}, ... node_params={'a': {'shape': 'rectangle'}}) <daft.PGM at 0x7f9bb48b0bb0>

class
pgmpy.base.DAG.
PDAG
(directed_ebunch=[], undirected_ebunch=[], latents=[])[source]¶ Class for representing PDAGs (also known as CPDAG). PDAGs are the equivance classes of DAGs and contain both directed and undirected edges.
**Note: In this class, undirected edges are represented using two edges in both direction i.e. an undirected edge between X  Y is represented using X > Y and X < Y.
Partially Directed Acyclic Graph (PDAG or CPDAG)¶
Class for representing PDAGs (also known as CPDAG). PDAGs are the equivance classes of DAGs and contain both directed and undirected edges.
**Note: In this class, undirected edges are represented using two edges in both direction i.e. an undirected edge between X  Y is represented using X > Y and X < Y.

pgmpy.base.PDAG.
adj
¶ Graph adjacency object holding the neighbors of each node.
This object is a readonly dictlike structure with node keys and neighbordict values. The neighbordict is keyed by neighbor to the edgedatadict. So G.adj[3][2][‘color’] = ‘blue’ sets the color of the edge (3, 2) to “blue”.
Iterating over G.adj behaves like a dict. Useful idioms include for nbr, datadict in G.adj[n].items():.
The neighbor information is also provided by subscripting the graph. So for nbr, foovalue in G[node].data(‘foo’, default=1): works.
For directed graphs, G.adj holds outgoing (successor) info.

pgmpy.base.PDAG.
degree
¶ A DegreeView for the Graph as G.degree or G.degree().
The node degree is the number of edges adjacent to the node. The weighted node degree is the sum of the edge weights for edges incident to that node.
This object provides an iterator for (node, degree) as well as lookup for the degree for a single node.
 Parameters
nbunch (single node, container, or all nodes (default= all nodes)) – The view will only report edges incident to these nodes.
weight (string or None, optional (default=None)) – The name of an edge attribute that holds the numerical value used as a weight. If None, then each edge has weight 1. The degree is the sum of the edge weights adjacent to the node.
 Returns
If a single node is requested
deg (int) – Degree of the node
OR if multiple nodes are requested
nd_iter (iterator) – The iterator returns twotuples of (node, degree).
See also
Examples
>>> G = nx.DiGraph() # or MultiDiGraph >>> nx.add_path(G, [0, 1, 2, 3]) >>> G.degree(0) # node 0 with degree 1 1 >>> list(G.degree([0, 1, 2])) [(0, 1), (1, 2), (2, 2)]

pgmpy.base.PDAG.
edges
¶ An OutEdgeView of the DiGraph as G.edges or G.edges().
edges(self, nbunch=None, data=False, default=None)
The OutEdgeView provides setlike operations on the edgetuples as well as edge attribute lookup. When called, it also provides an EdgeDataView object which allows control of access to edge attributes (but does not provide setlike operations). Hence, G.edges[u, v][‘color’] provides the value of the color attribute for edge (u, v) while for (u, v, c) in G.edges.data(‘color’, default=’red’): iterates through all the edges yielding the color attribute with default ‘red’ if no color attribute exists.
 Parameters
nbunch (single node, container, or all nodes (default= all nodes)) – The view will only report edges incident to these nodes.
data (string or bool, optional (default=False)) – The edge attribute returned in 3tuple (u, v, ddict[data]). If True, return edge attribute dict in 3tuple (u, v, ddict). If False, return 2tuple (u, v).
default (value, optional (default=None)) – Value used for edges that don’t have the requested attribute. Only relevant if data is not True or False.
 Returns
edges – A view of edge attributes, usually it iterates over (u, v) or (u, v, d) tuples of edges, but can also be used for attribute lookup as edges[u, v][‘foo’].
 Return type
OutEdgeView
Notes
Nodes in nbunch that are not in the graph will be (quietly) ignored. For directed graphs this returns the outedges.
Examples
>>> G = nx.DiGraph() # or MultiDiGraph, etc >>> nx.add_path(G, [0, 1, 2]) >>> G.add_edge(2, 3, weight=5) >>> [e for e in G.edges] [(0, 1), (1, 2), (2, 3)] >>> G.edges.data() # default data is {} (empty dict) OutEdgeDataView([(0, 1, {}), (1, 2, {}), (2, 3, {'weight': 5})]) >>> G.edges.data("weight", default=1) OutEdgeDataView([(0, 1, 1), (1, 2, 1), (2, 3, 5)]) >>> G.edges([0, 2]) # only edges incident to these nodes OutEdgeDataView([(0, 1), (2, 3)]) >>> G.edges(0) # only edges incident to a single node (use G.adj[0]?) OutEdgeDataView([(0, 1)])

pgmpy.base.PDAG.
in_degree
¶ An InDegreeView for (node, in_degree) or in_degree for single node.
The node in_degree is the number of edges pointing to the node. The weighted node degree is the sum of the edge weights for edges incident to that node.
This object provides an iteration over (node, in_degree) as well as lookup for the degree for a single node.
 Parameters
nbunch (single node, container, or all nodes (default= all nodes)) – The view will only report edges incident to these nodes.
weight (string or None, optional (default=None)) – The name of an edge attribute that holds the numerical value used as a weight. If None, then each edge has weight 1. The degree is the sum of the edge weights adjacent to the node.
 Returns
If a single node is requested
deg (int) – Indegree of the node
OR if multiple nodes are requested
nd_iter (iterator) – The iterator returns twotuples of (node, indegree).
See also
Examples
>>> G = nx.DiGraph() >>> nx.add_path(G, [0, 1, 2, 3]) >>> G.in_degree(0) # node 0 with degree 0 0 >>> list(G.in_degree([0, 1, 2])) [(0, 0), (1, 1), (2, 1)]

pgmpy.base.PDAG.
in_edges
¶ An InEdgeView of the Graph as G.in_edges or G.in_edges().
in_edges(self, nbunch=None, data=False, default=None):
 Parameters
nbunch (single node, container, or all nodes (default= all nodes)) – The view will only report edges incident to these nodes.
data (string or bool, optional (default=False)) – The edge attribute returned in 3tuple (u, v, ddict[data]). If True, return edge attribute dict in 3tuple (u, v, ddict). If False, return 2tuple (u, v).
default (value, optional (default=None)) – Value used for edges that don’t have the requested attribute. Only relevant if data is not True or False.
 Returns
in_edges – A view of edge attributes, usually it iterates over (u, v) or (u, v, d) tuples of edges, but can also be used for attribute lookup as edges[u, v][‘foo’].
 Return type
InEdgeView
See also

pgmpy.base.PDAG.
name
¶ String identifier of the graph.
This graph attribute appears in the attribute dict G.graph keyed by the string “name”. as well as an attribute (technically a property) G.name. This is entirely user controlled.

pgmpy.base.PDAG.
nodes
¶ A NodeView of the Graph as G.nodes or G.nodes().
Can be used as G.nodes for data lookup and for setlike operations. Can also be used as G.nodes(data=’color’, default=None) to return a NodeDataView which reports specific node data but no set operations. It presents a dictlike interface as well with G.nodes.items() iterating over (node, nodedata) 2tuples and G.nodes[3][‘foo’] providing the value of the foo attribute for node 3. In addition, a view G.nodes.data(‘foo’) provides a dictlike interface to the foo attribute of each node. G.nodes.data(‘foo’, default=1) provides a default for nodes that do not have attribute foo.
 Parameters
data (string or bool, optional (default=False)) – The node attribute returned in 2tuple (n, ddict[data]). If True, return entire node attribute dict as (n, ddict). If False, return just the nodes n.
default (value, optional (default=None)) – Value used for nodes that don’t have the requested attribute. Only relevant if data is not True or False.
 Returns
Allows setlike operations over the nodes as well as node attribute dict lookup and calling to get a NodeDataView. A NodeDataView iterates over (n, data) and has no set operations. A NodeView iterates over n and includes set operations.
When called, if data is False, an iterator over nodes. Otherwise an iterator of 2tuples (node, attribute value) where the attribute is specified in data. If data is True then the attribute becomes the entire data dictionary.
 Return type
NodeView
Notes
If your node data is not needed, it is simpler and equivalent to use the expression
for n in G
, orlist(G)
.Examples
There are two simple ways of getting a list of all nodes in the graph:
>>> G = nx.path_graph(3) >>> list(G.nodes) [0, 1, 2] >>> list(G) [0, 1, 2]
To get the node data along with the nodes:
>>> G.add_node(1, time="5pm") >>> G.nodes[0]["foo"] = "bar" >>> list(G.nodes(data=True)) [(0, {'foo': 'bar'}), (1, {'time': '5pm'}), (2, {})] >>> list(G.nodes.data()) [(0, {'foo': 'bar'}), (1, {'time': '5pm'}), (2, {})]
>>> list(G.nodes(data="foo")) [(0, 'bar'), (1, None), (2, None)] >>> list(G.nodes.data("foo")) [(0, 'bar'), (1, None), (2, None)]
>>> list(G.nodes(data="time")) [(0, None), (1, '5pm'), (2, None)] >>> list(G.nodes.data("time")) [(0, None), (1, '5pm'), (2, None)]
>>> list(G.nodes(data="time", default="Not Available")) [(0, 'Not Available'), (1, '5pm'), (2, 'Not Available')] >>> list(G.nodes.data("time", default="Not Available")) [(0, 'Not Available'), (1, '5pm'), (2, 'Not Available')]
If some of your nodes have an attribute and the rest are assumed to have a default attribute value you can create a dictionary from node/attribute pairs using the default keyword argument to guarantee the value is never None:
>>> G = nx.Graph() >>> G.add_node(0) >>> G.add_node(1, weight=2) >>> G.add_node(2, weight=3) >>> dict(G.nodes(data="weight", default=1)) {0: 1, 1: 2, 2: 3}

pgmpy.base.PDAG.
out_degree
¶ An OutDegreeView for (node, out_degree)
The node out_degree is the number of edges pointing out of the node. The weighted node degree is the sum of the edge weights for edges incident to that node.
This object provides an iterator over (node, out_degree) as well as lookup for the degree for a single node.
 Parameters
nbunch (single node, container, or all nodes (default= all nodes)) – The view will only report edges incident to these nodes.
weight (string or None, optional (default=None)) – The name of an edge attribute that holds the numerical value used as a weight. If None, then each edge has weight 1. The degree is the sum of the edge weights adjacent to the node.
 Returns
If a single node is requested
deg (int) – Outdegree of the node
OR if multiple nodes are requested
nd_iter (iterator) – The iterator returns twotuples of (node, outdegree).
Examples
>>> G = nx.DiGraph() >>> nx.add_path(G, [0, 1, 2, 3]) >>> G.out_degree(0) # node 0 with degree 1 1 >>> list(G.out_degree([0, 1, 2])) [(0, 1), (1, 1), (2, 1)]

pgmpy.base.PDAG.
out_edges
¶ An OutEdgeView of the DiGraph as G.edges or G.edges().
edges(self, nbunch=None, data=False, default=None)
The OutEdgeView provides setlike operations on the edgetuples as well as edge attribute lookup. When called, it also provides an EdgeDataView object which allows control of access to edge attributes (but does not provide setlike operations). Hence, G.edges[u, v][‘color’] provides the value of the color attribute for edge (u, v) while for (u, v, c) in G.edges.data(‘color’, default=’red’): iterates through all the edges yielding the color attribute with default ‘red’ if no color attribute exists.
 Parameters
nbunch (single node, container, or all nodes (default= all nodes)) – The view will only report edges incident to these nodes.
data (string or bool, optional (default=False)) – The edge attribute returned in 3tuple (u, v, ddict[data]). If True, return edge attribute dict in 3tuple (u, v, ddict). If False, return 2tuple (u, v).
default (value, optional (default=None)) – Value used for edges that don’t have the requested attribute. Only relevant if data is not True or False.
 Returns
edges – A view of edge attributes, usually it iterates over (u, v) or (u, v, d) tuples of edges, but can also be used for attribute lookup as edges[u, v][‘foo’].
 Return type
OutEdgeView
Notes
Nodes in nbunch that are not in the graph will be (quietly) ignored. For directed graphs this returns the outedges.
Examples
>>> G = nx.DiGraph() # or MultiDiGraph, etc >>> nx.add_path(G, [0, 1, 2]) >>> G.add_edge(2, 3, weight=5) >>> [e for e in G.edges] [(0, 1), (1, 2), (2, 3)] >>> G.edges.data() # default data is {} (empty dict) OutEdgeDataView([(0, 1, {}), (1, 2, {}), (2, 3, {'weight': 5})]) >>> G.edges.data("weight", default=1) OutEdgeDataView([(0, 1, 1), (1, 2, 1), (2, 3, 5)]) >>> G.edges([0, 2]) # only edges incident to these nodes OutEdgeDataView([(0, 1), (2, 3)]) >>> G.edges(0) # only edges incident to a single node (use G.adj[0]?) OutEdgeDataView([(0, 1)])

pgmpy.base.PDAG.
pred
¶ Graph adjacency object holding the predecessors of each node.
This object is a readonly dictlike structure with node keys and neighbordict values. The neighbordict is keyed by neighbor to the edgedatadict. So G.pred[2][3][‘color’] = ‘blue’ sets the color of the edge (3, 2) to “blue”.
Iterating over G.pred behaves like a dict. Useful idioms include for nbr, datadict in G.pred[n].items():. A dataview not provided by dicts also exists: for nbr, foovalue in G.pred[node].data(‘foo’): A default can be set via a default argument to the data method.

pgmpy.base.PDAG.
succ
¶ Graph adjacency object holding the successors of each node.
This object is a readonly dictlike structure with node keys and neighbordict values. The neighbordict is keyed by neighbor to the edgedatadict. So G.succ[3][2][‘color’] = ‘blue’ sets the color of the edge (3, 2) to “blue”.
Iterating over G.succ behaves like a dict. Useful idioms include for nbr, datadict in G.succ[n].items():. A dataview not provided by dicts also exists: for nbr, foovalue in G.succ[node].data(‘foo’): and a default can be set via a default argument to the data method.
The neighbor information is also provided by subscripting the graph. So for nbr, foovalue in G[node].data(‘foo’, default=1): works.
For directed graphs, G.adj is identical to G.succ.