Python 什么';从庞大的邻接列表中提取边列表的最有效方法是什么?

Python 什么';从庞大的邻接列表中提取边列表的最有效方法是什么?,python,csv,graph,Python,Csv,Graph,这可能是一个愚蠢的问题,但假设我有一个大的(~数十亿行)CSV文件,其中包含邻接列表,其中顶点由字符串表示,如: +------------+---------------------------+ | id | neighbors | +------------+---------------------------+ | 'james' | 'michael, jane, pete' | | 'doug' | 'cliff

这可能是一个愚蠢的问题,但假设我有一个大的(~数十亿行)CSV文件,其中包含邻接列表,其中顶点由字符串表示,如:

+------------+---------------------------+
|     id     |         neighbors         |
+------------+---------------------------+
| 'james'    | 'michael, jane, pete'     |
| 'doug'     | 'cliff'                   |
| 'amy'      | 'bobby, russell, richard' |
| 'richard'  | 'kam, earl, cliff'        |
| 'marshawn' |                           |
| 'bobby'    | 'emily, james, doug'      |
+------------+---------------------------+
从这些类型的邻接列表中,我所要做的就是输出一个顶点集和一个由无向的对顶点组成的边集。仅此而已

实现这一点最有效的策略是什么,我们如何在Python中实现它?

为了简洁地概述下面的算法,让我们:

  • add('bobby')
    :将顶点“bobby”添加到顶点集的操作
  • edge('bobby','emily')
    :将('bobby','emily')添加到边缘集的操作
  • ingraph(“bobby”)
    :检查顶点“bobby”是否在顶点集中
假设我们从一个空图开始,按顺序添加顶点。然后,我的第一次尝试(在非常原始的伪代码中)是这样的:

ids = [...all id's in the CSV...]
unexplored = list(ids)

for i in ids:
    add(i)
    for j in unexplored:
        if i in neighbors(j):
            if not ingraph(j): add(j)
            edge(i, j)              
    del unexplored[0]
  • 是否有一种明显的方法来改进这个算法(独立于Python)
  • 用Python实现这种解决方案的最佳方法是什么?在原始CSV文件中迭代?将其加载到
    pandas
    并使用
    numpy
    以某种方式对其进行矢量化(假设我有足够的内存…)

  • 编辑:通过写“邻居”,我希望清楚地表明我只想要一个无向图。如果这不明显,很抱歉。

    编辑2-好的,无向图,您只想输出边和顶点:derM为您准备好了。只需注意数据集的大小—数据集增长很快。这不是最初关于创建一个图而不是提取一个边列表吗?

    如果我理解正确,您希望将图表示为G(V,E),其中V和E是两个具有V惯性和EDGE的集合

    由于EDGE是无向的,您需要考虑某种方式来表示它们。要么你不关心它们的方向,总是检查两个方向中的一个方向是否有边,要么你规范化它们,例如对元组使用字母数字排序

    因此,我们假设您选择后者,那么E是一组元组,其中条目遵循严格的顺序

    e = (v1, v2), v1 < v2.
    
    e=(v1,v2),v1
    使用此定义,您只需逐行处理文件,将ID添加到
    集合V
    ,创建包含邻域
    (ID,neighbor)
    (neighbor,ID)
    的元组,具体取决于它们的字母数字顺序,并将其添加到
    集合E

    如果您坚持边的规范表示,Python会注意,在
    集合
    中不会有重复的边,因为它被定义为唯一元素的无序集合。

    只要你能假设你的文件是正确的,并且没有没有没有端点的边(因为缺少ID),你就可以先创建边,然后再创建边-一旦你到达相应的行,你就可以创建顶点。

    如果你不能保持这个假设,你仍然可以用这种方式创建你的图形表示,你只需要在最后实现一些清理,在那里你再次迭代边集,检查是否有任何边在无处悬空(指向一个不存在的顶点),并通过删除这个边,或者创建顶点-任何适合您需要的方法。

    为了更高效地查找,我会使用哈希数据结构,而不是列表。您是否可以非常高效地查询边(O(1))?否则,您可能需要实现这一点。然后你可以用O(行)来处理列表。你必须比“图形”更具体。根据许多定义,您的巨大CSV文件已经是一个图形。是否需要创建特定的图形表示?您是否需要高效地支持某些操作?您在这里的实际需求是什么?@user2357112:很好;我道歉。所谓“图”,我只是指标准的数学定义:一组顶点V和一组由成对顶点组成的边E。所以基本上,我只想要一种建立边缘集的方法。我会编辑。你的假设很奇怪,因为示例数据有邻居。我从来没有和一个不住在我旁边的人住在一起。根据示例数据:博比是艾米的邻居,但艾米不是博比的邻居。邻接列表通常用于有向图。哦,糟了。我刚才也独立意识到了这一点。谢谢你指出这一点。