PySpark GraphFrame

时间:2016-06-09 12:40:44

标签: python pyspark graphframes

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参数的交集的图表?

2 个答案:

答案 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))

有人有更好的方法吗?我会很高兴看到它。