将 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" 解决此问题的方法以及对我的新手来说很简单的方法很感兴趣。

您可以使用 mapset_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