Преобразование списка узлов и ребер панды из меток узла в индекс узла - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть аккуратное представление графа или сети, выраженное в виде двух отдельных csvs;один для узлов, один для ребер с весами.Я прочитал их из csv в pandas dataframes в Python 3.

Я создаю некоторые аналогичные dataframes, используя различные методы здесь, но использую их для иллюстрации проблемы.

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 соответственно.Я не против, если решение займет несколько минут.

Я могу получить информацию, которая мне нужна, но не могу присвоить ее новому столбцу панд в кадре данных ребер.

Я могу получить нужные мне индексы с помощью цикла, но есть ли лучший способ сделать это в пандах, могу ли я векторизовать проблему, как в 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_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 голосов
/ 21 ноября 2018

Вы можете использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...