将 pandas 个节点和边列表从节点标签转换为节点索引
Converting a pandas nodes and edges list from node labels to node index
我有一个 tidy representation 表示为两个单独的 csvs 的图形或网络;一种用于节点,一种用于具有权重的边。我已经将它们从 csv 读取到 Python 中的 pandas 数据帧 3.
我在这里使用不同的方法创建了一些类似的数据帧,但将它们用于说明问题。
import pandas as pd
# i have a nodes list
nodes = {'page': ['/', '/a', '/b']}
# the data is actually read in from csv
nodes = pd.DataFrame.from_dict(nodes)
nodes
哪个 returns 节点列表已被默认方法自动索引(无论是什么;我读到它在 Python 版本之间有所不同,但这不应该影响问题)。
page
0 /
1 /a
2 /b
边缘列表是:
# and an edges list which uses node label; source and destination
# need to convert into indexes from nodes
edges = {'source_node': ['/', '/a', '/b', '/a'],
'destination_node': ['/b', '/b', '/', '/'],
'weight': [5, 2, 10, 5]}
# the data is actually read in from csv
edges = pd.DataFrame.from_dict(edges)
edges
看起来像:
source_node destination_node weight
0 / /b 5
1 /a /b 2
2 /b / 10
3 /a / 5
问题在这里,源节点和目标节点是标签,而不是前一个数据帧中的正确节点索引。我想要一个边缘 pandas 数据框,其中包含标记节点的适当索引而不是它们的标签。我可以在数据管道的上游执行此操作,但为了方便起见,我想在此处修复此问题。节点数和边数分别为22 k和45 k。我不介意解决方案是否需要几分钟 运行。
我可以获得所需的信息,但无法将其分配给边缘数据框中的新 pandas 列。
我可以通过循环获得我想要的索引,但是在 pandas 中是否有更好的方法来做到这一点,我可以像在 R 中那样向量化问题吗?
for i in edges["source_node"]:
print(nodes[nodes.page == i].index.values.astype(int)[0])
for i in edges["destination_node"]:
print(nodes[nodes.page == i].index.values.astype(int)[0])
0
1
2
1
2
2
0
0
以及如何将其作为两个新列放入我的边缘数据框中,一个称为 'source',一个称为 'destination'。我想要的是:
source_node destination_node weight source destination
0 / /b 5 0 2
1 /a /b 2 1 2
2 /b / 10 2 0
3 /a / 5 1 0
出现以下错误并且开始时看起来不正确:
edges['source'] = for i in edges["source_node"]:
nodes[nodes.page == i].index.values.astype(int)[0]
edges['destination'] = for i in edges["destination_node"]:
nodes[nodes.page == i].index.values.astype(int)[0]
由于我是 Python 的新手,我对 "Pythonic" 解决此问题的方法以及对我的新手来说很简单的方法很感兴趣。
您可以使用 map
和 set_index
:
nodelist = nodes.reset_index().set_index('page').squeeze()
或@mammykins 建议在现实世界中使用样本:
nodelist = nodelist.loc[~nodelist.index.duplicated(keep='first')]
edges['source'] = edges.source_node.map(nodelist)
edges['destination'] = edges.destination_node.map(nodelist)
print(edges)
输出:
source_node destination_node weight source destination
0 / /b 5 0 2
1 /a /b 2 1 2
2 /b / 10 2 0
3 /a / 5 1 0
我有一个 tidy representation 表示为两个单独的 csvs 的图形或网络;一种用于节点,一种用于具有权重的边。我已经将它们从 csv 读取到 Python 中的 pandas 数据帧 3.
我在这里使用不同的方法创建了一些类似的数据帧,但将它们用于说明问题。
import pandas as pd
# i have a nodes list
nodes = {'page': ['/', '/a', '/b']}
# the data is actually read in from csv
nodes = pd.DataFrame.from_dict(nodes)
nodes
哪个 returns 节点列表已被默认方法自动索引(无论是什么;我读到它在 Python 版本之间有所不同,但这不应该影响问题)。
page
0 /
1 /a
2 /b
边缘列表是:
# and an edges list which uses node label; source and destination
# need to convert into indexes from nodes
edges = {'source_node': ['/', '/a', '/b', '/a'],
'destination_node': ['/b', '/b', '/', '/'],
'weight': [5, 2, 10, 5]}
# the data is actually read in from csv
edges = pd.DataFrame.from_dict(edges)
edges
看起来像:
source_node destination_node weight
0 / /b 5
1 /a /b 2
2 /b / 10
3 /a / 5
问题在这里,源节点和目标节点是标签,而不是前一个数据帧中的正确节点索引。我想要一个边缘 pandas 数据框,其中包含标记节点的适当索引而不是它们的标签。我可以在数据管道的上游执行此操作,但为了方便起见,我想在此处修复此问题。节点数和边数分别为22 k和45 k。我不介意解决方案是否需要几分钟 运行。
我可以获得所需的信息,但无法将其分配给边缘数据框中的新 pandas 列。
我可以通过循环获得我想要的索引,但是在 pandas 中是否有更好的方法来做到这一点,我可以像在 R 中那样向量化问题吗?
for i in edges["source_node"]:
print(nodes[nodes.page == i].index.values.astype(int)[0])
for i in edges["destination_node"]:
print(nodes[nodes.page == i].index.values.astype(int)[0])
0
1
2
1
2
2
0
0
以及如何将其作为两个新列放入我的边缘数据框中,一个称为 'source',一个称为 'destination'。我想要的是:
source_node destination_node weight source destination
0 / /b 5 0 2
1 /a /b 2 1 2
2 /b / 10 2 0
3 /a / 5 1 0
出现以下错误并且开始时看起来不正确:
edges['source'] = for i in edges["source_node"]:
nodes[nodes.page == i].index.values.astype(int)[0]
edges['destination'] = for i in edges["destination_node"]:
nodes[nodes.page == i].index.values.astype(int)[0]
由于我是 Python 的新手,我对 "Pythonic" 解决此问题的方法以及对我的新手来说很简单的方法很感兴趣。
您可以使用 map
和 set_index
:
nodelist = nodes.reset_index().set_index('page').squeeze()
或@mammykins 建议在现实世界中使用样本:
nodelist = nodelist.loc[~nodelist.index.duplicated(keep='first')]
edges['source'] = edges.source_node.map(nodelist)
edges['destination'] = edges.destination_node.map(nodelist)
print(edges)
输出:
source_node destination_node weight source destination
0 / /b 5 0 2
1 /a /b 2 1 2
2 /b / 10 2 0
3 /a / 5 1 0