PySpark图框架的真子图

xwbd5t1u  于 2022-12-28  发布在  Spark
关注(0)|答案(4)|浏览(160)

graphframes是一个基于PySpark DataFrames的网络分析工具。以下代码是子图示例教程的修改版本:

from graphframes.examples import Graphs
import graphframes
g = Graphs(sqlContext).friends()  # Get example graph
# Select subgraph of users older than 30
v2 = g.vertices.filter("age > 30")
g2 = graphframes.GraphFrame(v2, g.edges)

人们会期望新的图g2与原始图g相比包含更少的节点和更少的边,然而,情况并非如此:

print(g.vertices.count(), g.edges.count())
print(g2.vertices.count(), g2.edges.count())

给出输出:

(6, 7)
(7, 4)

很明显,生成的图形包含不存在的节点的边。更令人不安的是g.degreesg2.degrees是相同的。这意味着至少有一些图形功能忽略了节点信息。是否有一种好方法可以确保GraphFrame只使用提供的nodesedges参数的交集创建图形?

cs7cruho

cs7cruho1#

我用来绘制图形框架的一个方法是使用motifs:

motifs = g.find("(a)-[e]->(b)").filter(<conditions for a,b or e>)
new_vertices = sqlContext.createDataFrame(motifs.map(lambda row: row.a).union(motifs.map(lambda row: row.b)).distinct())
new_edges = sqlContext.createDataFrame(motifs.map(lambda row:row.e).distinct())
new_graph = GraphFrame(new_vertices,new_edges)

虽然这看起来更复杂,可能需要更长的运行时间,但对于更复杂的图形查询,这可以很好地作为一个单独的实体与图形框架交互,而不是作为单独的顶点和边。因此,过滤顶点也会影响图形框架中剩下的边。

pinkon5k

pinkon5k2#

有意思..我看不出结果:

>>> from graphframes.examples import Graphs
>>> import graphframes
>>> g = Graphs(sqlContext).friends()  # Get example graph
>>> # Select subgraph of users older than 30
... v2 = g.vertices.filter("age > 30")
>>> g2 = graphframes.GraphFrame(v2, g.edges)
>>> print(g.vertices.count(), g.edges.count())
(6, 7)
>>> print(g2.vertices.count(), g2.edges.count())
(4, 7)

GraphFrames到目前为止还没有检查图形是否有效--即所有的边都连接到顶点等等,在图形构造的时候。但是在过滤器之后顶点的数量是否正确?

9rbhqvlz

9rbhqvlz3#

我的变通方法可能不是完美的,但它们对我很有效。
我得到的问题陈述:具有节点的过滤集合filtered_nodes,我们只希望具有来自原始图的包括来自filtered_nodes的节点的边。

    • 方法1**:使用联接(开销大)
edgesframe = graphframe.edges
src_join = edgesframe.join(filtered_nodes, (edgesframe.src == subgraph_nodes.id), "inner").withColumnRenamed("src", "srcto")
dst_join = edgesframe.join(filtered_nodes, (edgesframe.dst == subgraph_nodes.id), "inner").withColumnRenamed("dst", "dstto")
final_join = src_join.join(dst_join, (src_join.src == dst_join.src) & (src_join.dst == dst_join.dst), "inner").select("src", "dst")
g2 = GraphFrame(filtered_nodes, final_join)
    • 方法二**:使用collected集合作为 * isin * 方法的列表引用(我只在过滤器节点的小集合上使用它)
edgesframe = graphframe.edges
collected_nodes = subgraph_nodes.select("columnWeUseForReference").rdd.map(lambda r: r[0]).collect()
edgs = edgesframe.filter(edgesframe.src.isin(collected_nodes) & edgesframe.dst.isin(collected_nodes))

有人有更好的办法吗?我很乐意去看看。

hgc7kmma

hgc7kmma4#

我建议使用dropIsolatedVertices()。

相关问题