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.degrees
和g2.degrees
是相同的。这意味着至少一些图形功能忽略了节点信息。是否有一种确保GraphFrame
创建的好方法
仅使用提供的nodes
和edges
参数的交集的图表?
答案 0 :(得分:1)
有趣......我无法看到结果:
>>> 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不会检查图表是否有效 - 即。在图形构造时,所有边都连接到顶点,依此类推。但看起来过滤后的顶点数是否正确?
答案 1 :(得分:0)
我的变通办法可能不是完美的,但它们对我有用。
我得到的问题陈述:有一个过滤的节点集合 filtered_nodes,我们只希望原始图中的边包含来自 filtered_nodes 的节点。< /p>
方法 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)
方法 2:使用收集的集合作为 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))
有人有更好的方法吗?我会很高兴看到它。