"""节点数据x-y对的生成器。"""
import networkx as nx
__all__ = ["node_attribute_xy", "node_degree_xy"]
[docs]
@nx._dispatchable(node_attrs="attribute")
def node_attribute_xy(G, attribute, nodes=None):
"""生成图 `G` 中所有边的节点属性值的 2-元组。
此生成器针对 `G` 中与 `nodes` 中的节点相邻的每条边,生成一个形如 ``(属性值, 属性值)`` 的 2-元组,用于指定的节点属性。
Parameters
----------
G: NetworkX 图
attribute: 键
节点属性键。
nodes: 列表或可迭代对象(可选)
仅使用与指定节点相邻的边。
默认是所有节点。
Yields
------
(x, y): 2-元组
生成 (属性, 属性) 值的 2-元组。
Examples
--------
>>> G = nx.DiGraph()
>>> G.add_node(1, color="red")
>>> G.add_node(2, color="blue")
>>> G.add_node(3, color="green")
>>> G.add_edge(1, 2)
>>> list(nx.node_attribute_xy(G, "color"))
[('red', 'blue')]
Notes
-----
对于无向图,每条边会产生两次,一次是边表示 (u, v),另一次是 (v, u),自环边除外,它们只出现一次。
"""
if nodes is None:
nodes = set(G)
else:
nodes = set(nodes)
Gnodes = G.nodes
for u, nbrsdict in G.adjacency():
if u not in nodes:
continue
uattr = Gnodes[u].get(attribute, None)
if G.is_multigraph():
for v, keys in nbrsdict.items():
vattr = Gnodes[v].get(attribute, None)
for _ in keys:
yield (uattr, vattr)
else:
for v in nbrsdict:
vattr = Gnodes[v].get(attribute, None)
yield (uattr, vattr)
[docs]
@nx._dispatchable(edge_attrs="weight")
def node_degree_xy(G, x="out", y="in", weight=None, nodes=None):
"""生成 `G` 中边的 ``(度数, 度数)`` 值的 2-元组。
这个生成器为 `G` 中与 `nodes` 中的节点相邻的每条边生成一个形式为 ``(度数, 度数)`` 的 2-元组。当指定了 `weight` 属性时,节点的度数是加权的。
Parameters
----------
G: NetworkX 图
x: 字符串 ('in','out')
源节点的度数类型(仅限有向图)。
y: 字符串 ('in','out')
目标节点的度数类型(仅限有向图)。
weight: 字符串或 None, 可选 (默认=None)
存储用作权重的数值的边属性。如果为 None,则每条边的权重为 1。
度数是与节点相邻的边权重的总和。
nodes: 列表或可迭代对象 (可选)
仅使用与指定节点相邻的边。默认是所有节点。
Yields
------
(x, y): 2-元组
生成 (度数, 度数) 值的 2-元组。
Examples
--------
>>> G = nx.DiGraph()
>>> G.add_edge(1, 2)
>>> list(nx.node_degree_xy(G, x="out", y="in"))
[(1, 1)]
>>> list(nx.node_degree_xy(G, x="in", y="out"))
[(0, 0)]
Notes
-----
对于无向图,每条边会产生两次,一次是边表示 (u, v),另一次是 (v, u),自环边除外,它们只出现一次。
"""
nodes = set(G) if nodes is None else set(nodes)
if G.is_directed():
direction = {"out": G.out_degree, "in": G.in_degree}
xdeg = direction[x]
ydeg = direction[y]
else:
xdeg = ydeg = G.degree
for u, degu in xdeg(nodes, weight=weight):
# use G.edges to treat multigraphs correctly
neighbors = (nbr for _, nbr in G.edges(u) if nbr in nodes)
for _, degv in ydeg(neighbors, weight=weight):
yield degu, degv