为节点分配颜色时出现 KeyError
KeyError when assign colours to nodes
我在尝试创建网络时收到 KeyError。
我的数据集是
Node Neighbors Colour Weight
Luke Alte orange 3
Luke John orange 3
Michael Laura red 43
Ludo Stella orange 21
Alte Ludo blue 24
Alte Luke blue 24
上面的table按节点显示链接:
- 节点卢克与阿尔特和约翰有联系。它的边权重为 3,颜色为橙色
- 节点迈克尔与劳拉有联系。它的重量为 43,颜色为红色
- node Ludo 与 Stella 关联。它的权重为 21,颜色为橙色
- node Alte 与 Luke 和 Ludo 有联系。它有蓝色和重量 24
做如下:
NROWS = None
def get_graph_from_pandas(df):
G = nx.DiGraph() # assuming the graph is directed since e.g node 1 has
# 3 as neighbour but 3 doesnt have 1 as neighbour
for row in df.itertuples(): # row is the row of the dataframe
n = row.Node
w = row.Weight
c = row.Colour
neighbors = row.Neighbors
G.add_node(n, weight = w, colour = c)
for neigh in neighbors:
#add edge weights here, attribute of G.add_edge
G.add_edge(n,neigh)
return G
G = get_graph_from_pandas(df)
print("Done.")
print("Total number of nodes: ", G.number_of_nodes())
print("Total number of edges: ", G.number_of_edges())
pos = nx.draw(G, with_labels=True,
node_color=[node[1]['colour'] for node in G.nodes(data=True)],
node_size=200)
给我一个 KeyError: 'colour'.
当我打印时
for node in G.nodes(data=True):
try:
node[1]['colour']
except KeyError:
print(node)
我明白了
('A', {})
('l', {})
('t', {})
('e', {})
你能解释一下是什么导致了这个错误吗?谢谢
更新:我认为错误来自这里
for neigh in neighbors:
#add edge weights here, attribute of G.add_edge
G.add_edge(n,neigh)
df.Neighbors
中的每一项都是一个字符串。当您使用 for neigh in neighbors:
对其进行迭代时,您将邻居的每个字符添加到该节点。例如第一个节点看起来像
>>> G.nodes
>>> NodeView(('Luke', 'A', 'l', 't', 'e'))
只要每行只有一个邻居,将for循环替换为
# for neigh in neighbors:
# #add edge weights here, attribute of G.add_edge
# G.add_edge(n,neigh)
G.add_edge(n,neighbors)
尽管这并不能缓解 KeyError
。
虽然 'John'
、'Laura'
和 'Stella'
是邻居,但它们也是图中的节点,但它们是用 .add_edge
创建的,并且从来没有颜色 分配给他们。
>>> for thing in G.nodes.items():
... print(thing)
('Luke', {'weight': 3, 'colour': 'orange'})
('Alte', {'weight': 24, 'colour': 'blue'})
('John', {})
('Michael', {'weight': 43, 'colour': 'red'})
('Laura', {})
('Ludo', {'weight': 21, 'colour': 'orange'})
('Stella', {})
您可以在迭代之前先使用 default 属性添加这些节点:
...
G.add_nodes_from(df.Neighbors,colour='white',weight=0)
for row in df.itertuples(): # row is the row of the dataframe
...
如果您的节点属性可以以大写字母开头,则可以编写图形构造:
def get_graph_from_pandas(df):
G = nx.DiGraph() # assuming the graph is directed since e.g node 1 has
# 3 as neighbour but 3 doesnt have 1 as neighbour
G.add_nodes_from(df.Neighbors,Colour='white',Weight=0)
G.add_edges_from(df[['Node','Neighbors']].itertuples(index=False))
dg = df.set_index('Node')
G.add_nodes_from(dg[['Colour','Weight']].T.to_dict().items())
return G
>>> for thing in G.nodes(data=True):
... print(thing)
('Alte', {'Colour': 'blue', 'Weight': 24})
('John', {'Colour': 'white', 'Weight': 0})
('Laura', {'Colour': 'white', 'Weight': 0})
('Stella', {'Colour': 'white', 'Weight': 0})
('Ludo', {'Colour': 'orange', 'Weight': 21})
('Luke', {'Colour': 'orange', 'Weight': 3})
('Michael', {'Colour': 'red', 'Weight': 43})
>>> for thing in G.edges(data=True):
... print(thing)
('Alte', 'Ludo', {})
('Alte', 'Luke', {})
('Ludo', 'Stella', {})
('Luke', 'Alte', {})
('Luke', 'John', {})
('Michael', 'Laura', {})
您可以直接从 G.nodes.items
获取节点颜色
pos = nx.draw(G, with_labels=True,
node_color=[d['Colour'] for n,d in G.nodes.items()],
node_size=200)
或nx.get_node_attributes
pos = nx.draw(G, with_labels=True,
node_color=nx.get_node_attributes(G,'Colour').values(),
node_size=200)
二战答案解决了一个问题。
但是有一些问题需要解决:
只有Node栏中的节点会有颜色,只在Neighbors栏中引入的用户将在G.add_edge(n,neighbor)
中创建,并且不会分配颜色。
您需要决定为这些节点设置哪种颜色。
您要分配给边的权重正在分配给节点。
df = pd.DataFrame( data = {"Node": ["Luke", "Luke", "Michael", "Ludo", "Alte", "Alte"],
"Neighbors": ["Ludo", "John", "Laura", "Stella", "Ludo", "Luke"],
"Colour": ["orange", "orange", "red", "orange", "blue", "blue"],
"Weight": [3, 3 ,43, 21, 24, 24]
}
)
NROWS = None
def get_graph_from_pandas(df, v = False):
G = nx.DiGraph() # assuming the graph is directed since e.g node 1 has
# 3 as neighbour but 3 doesnt have 1 as neighbour
for row in df.itertuples():
print(row)
n = row.Node
w = row.Weight
c = row.Colour
neighbor = row.Neighbors
G.add_node(n, weight = w, colour = c) # only nodes in column Node will have color
# users that are only introduced in Neighbors column dwont have column
if neighbor not in G.nodes:
G.add_node(neighbor, weight = w, colour = "yellow") # this will set the default color to yellow
G.add_edge(n,neighbor, weight = w) # weight of edge
return G
G = get_graph_from_pandas(df, v = False)
print("Done.")
print("Total number of nodes: ", graph.number_of_nodes())
print("Total number of edges: ", graph.number_of_edges())
fig = plt.figure(figsize=(2,2))
pos = nx.draw(G, with_labels=True,
node_color=[node[1]['colour'] for node in G.nodes(data=True)],
node_size=200)
for node in G.nodes(data=True):
try:
node[1]['colour']
except KeyError:
print(node)
我在尝试创建网络时收到 KeyError。
我的数据集是
Node Neighbors Colour Weight
Luke Alte orange 3
Luke John orange 3
Michael Laura red 43
Ludo Stella orange 21
Alte Ludo blue 24
Alte Luke blue 24
上面的table按节点显示链接:
- 节点卢克与阿尔特和约翰有联系。它的边权重为 3,颜色为橙色
- 节点迈克尔与劳拉有联系。它的重量为 43,颜色为红色
- node Ludo 与 Stella 关联。它的权重为 21,颜色为橙色
- node Alte 与 Luke 和 Ludo 有联系。它有蓝色和重量 24
做如下:
NROWS = None
def get_graph_from_pandas(df):
G = nx.DiGraph() # assuming the graph is directed since e.g node 1 has
# 3 as neighbour but 3 doesnt have 1 as neighbour
for row in df.itertuples(): # row is the row of the dataframe
n = row.Node
w = row.Weight
c = row.Colour
neighbors = row.Neighbors
G.add_node(n, weight = w, colour = c)
for neigh in neighbors:
#add edge weights here, attribute of G.add_edge
G.add_edge(n,neigh)
return G
G = get_graph_from_pandas(df)
print("Done.")
print("Total number of nodes: ", G.number_of_nodes())
print("Total number of edges: ", G.number_of_edges())
pos = nx.draw(G, with_labels=True,
node_color=[node[1]['colour'] for node in G.nodes(data=True)],
node_size=200)
给我一个 KeyError: 'colour'.
当我打印时
for node in G.nodes(data=True):
try:
node[1]['colour']
except KeyError:
print(node)
我明白了
('A', {})
('l', {})
('t', {})
('e', {})
你能解释一下是什么导致了这个错误吗?谢谢
更新:我认为错误来自这里
for neigh in neighbors:
#add edge weights here, attribute of G.add_edge
G.add_edge(n,neigh)
df.Neighbors
中的每一项都是一个字符串。当您使用 for neigh in neighbors:
对其进行迭代时,您将邻居的每个字符添加到该节点。例如第一个节点看起来像
>>> G.nodes
>>> NodeView(('Luke', 'A', 'l', 't', 'e'))
只要每行只有一个邻居,将for循环替换为
# for neigh in neighbors:
# #add edge weights here, attribute of G.add_edge
# G.add_edge(n,neigh)
G.add_edge(n,neighbors)
尽管这并不能缓解 KeyError
。
虽然 'John'
、'Laura'
和 'Stella'
是邻居,但它们也是图中的节点,但它们是用 .add_edge
创建的,并且从来没有颜色 分配给他们。
>>> for thing in G.nodes.items():
... print(thing)
('Luke', {'weight': 3, 'colour': 'orange'})
('Alte', {'weight': 24, 'colour': 'blue'})
('John', {})
('Michael', {'weight': 43, 'colour': 'red'})
('Laura', {})
('Ludo', {'weight': 21, 'colour': 'orange'})
('Stella', {})
您可以在迭代之前先使用 default 属性添加这些节点:
...
G.add_nodes_from(df.Neighbors,colour='white',weight=0)
for row in df.itertuples(): # row is the row of the dataframe
...
如果您的节点属性可以以大写字母开头,则可以编写图形构造:
def get_graph_from_pandas(df):
G = nx.DiGraph() # assuming the graph is directed since e.g node 1 has
# 3 as neighbour but 3 doesnt have 1 as neighbour
G.add_nodes_from(df.Neighbors,Colour='white',Weight=0)
G.add_edges_from(df[['Node','Neighbors']].itertuples(index=False))
dg = df.set_index('Node')
G.add_nodes_from(dg[['Colour','Weight']].T.to_dict().items())
return G
>>> for thing in G.nodes(data=True):
... print(thing)
('Alte', {'Colour': 'blue', 'Weight': 24})
('John', {'Colour': 'white', 'Weight': 0})
('Laura', {'Colour': 'white', 'Weight': 0})
('Stella', {'Colour': 'white', 'Weight': 0})
('Ludo', {'Colour': 'orange', 'Weight': 21})
('Luke', {'Colour': 'orange', 'Weight': 3})
('Michael', {'Colour': 'red', 'Weight': 43})
>>> for thing in G.edges(data=True):
... print(thing)
('Alte', 'Ludo', {})
('Alte', 'Luke', {})
('Ludo', 'Stella', {})
('Luke', 'Alte', {})
('Luke', 'John', {})
('Michael', 'Laura', {})
您可以直接从 G.nodes.items
pos = nx.draw(G, with_labels=True,
node_color=[d['Colour'] for n,d in G.nodes.items()],
node_size=200)
或nx.get_node_attributes
pos = nx.draw(G, with_labels=True,
node_color=nx.get_node_attributes(G,'Colour').values(),
node_size=200)
二战答案解决了一个问题。
但是有一些问题需要解决:
只有Node栏中的节点会有颜色,只在Neighbors栏中引入的用户将在
G.add_edge(n,neighbor)
中创建,并且不会分配颜色。 您需要决定为这些节点设置哪种颜色。您要分配给边的权重正在分配给节点。
df = pd.DataFrame( data = {"Node": ["Luke", "Luke", "Michael", "Ludo", "Alte", "Alte"],
"Neighbors": ["Ludo", "John", "Laura", "Stella", "Ludo", "Luke"],
"Colour": ["orange", "orange", "red", "orange", "blue", "blue"],
"Weight": [3, 3 ,43, 21, 24, 24]
}
)
NROWS = None
def get_graph_from_pandas(df, v = False):
G = nx.DiGraph() # assuming the graph is directed since e.g node 1 has
# 3 as neighbour but 3 doesnt have 1 as neighbour
for row in df.itertuples():
print(row)
n = row.Node
w = row.Weight
c = row.Colour
neighbor = row.Neighbors
G.add_node(n, weight = w, colour = c) # only nodes in column Node will have color
# users that are only introduced in Neighbors column dwont have column
if neighbor not in G.nodes:
G.add_node(neighbor, weight = w, colour = "yellow") # this will set the default color to yellow
G.add_edge(n,neighbor, weight = w) # weight of edge
return G
G = get_graph_from_pandas(df, v = False)
print("Done.")
print("Total number of nodes: ", graph.number_of_nodes())
print("Total number of edges: ", graph.number_of_edges())
fig = plt.figure(figsize=(2,2))
pos = nx.draw(G, with_labels=True,
node_color=[node[1]['colour'] for node in G.nodes(data=True)],
node_size=200)
for node in G.nodes(data=True):
try:
node[1]['colour']
except KeyError:
print(node)