将熊猫节点和边缘列表从节点标签转换为节点索引

时间:2018-11-20 20:53:36

标签: python pandas nodes edges

我有一个tidy representation的图形或网络表示为两个单独的csv;一个用于节点,一个用于具有权重的边。我已经将它们从csv中读取到Python 3中的pandas数据框中。

我在这里使用不同的方法创建了一些类似的数据框,但是将它们用于说明问题。

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

哪个返回的节点列表已被默认方法自动索引(无论如何;我读到的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

在这里看到了问题,源节点和目标节点是标签,而不是前一个数据帧中的正确节点索引。我想要一个带有标记节点而不是其标签的适当索引的边缘熊猫数据框。我可以在数据管道的上游进行此操作,但为了方便起见,在此处进行修复。节点和边的数量分别为22 k和45 k。我不介意该解决方案是否需要几分钟的时间。

我可以获得我想要的信息,但是无法将其分配给edge数据框中的新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

以及如何将其作为两列新列添加到我的Edge数据框中,一列称为“源”,另一列称为“目标”。我想要的是:

    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”方式以及对我的新手来说很简单的方法感兴趣。

1 个答案:

答案 0 :(得分:1)

您可以使用import csv from collections import defaultdict, OrderedDict def convert(data): try: return int(data) except ValueError: return 0 with open('MonthData1.csv', 'r') as file1: read_file = csv.reader(file1, delimiter=';') delheader = next(read_file) data = defaultdict(int) for line in read_file: valuedata = max(0, sum([convert(i) for i in line[1:5]])) data[line[0].split()[0]] += valuedata previous_values = [] for key, value in OrderedDict(sorted(data.items())).items(): print('{} {}'.format(key, value + sum(previous_values))) previous_values.append(value) map

set_index

或建议在现实世界中使用@mammykins:

nodelist = nodes.reset_index().set_index('page').squeeze()

输出:

nodelist = nodelist.loc[~nodelist.index.duplicated(keep='first')]


edges['source'] = edges.source_node.map(nodelist)
edges['destination'] = edges.destination_node.map(nodelist)

print(edges)