3. GraphFrames 入门:安装配置与图属性查询
GraphFrames 是构建在 Spark DataFrame 之上的图处理库,将图顶点和边统一为 DataFrame 进行管理,天然支持 DataFrame 的 Catalyst 优化、Tungsten 内存管理与 DataFrame 算子。本章从安装配置开始,逐步建立顶点 DataFrame 与边 DataFrame,并完成图的基本属性查询。
3.1 GraphFrames 安装与配置
GraphFrames 目前由 Databricks 维护,支持 Spark 2.4+ 及 Spark 3.x 系列。安装方式分为 Spark Shell / Jupyter 动态加载 与 Maven / SBT 项目依赖 两种。
| 环境 | 安装方式 | 示例命令 / 配置 |
|---|---|---|
| Spark Shell / PySpark | --packages 参数 | --packages graphframes:graphframes:0.8.2-spark3.2-s_2.12 |
| Jupyter Notebook | spark.jars.packages | spark = SparkSession.builder.config("spark.jars.packages", "graphframes:graphframes:0.8.2-spark3.2-s_2.12").getOrCreate() |
| Maven 项目 | pom.xml 依赖 | <groupId>graphframes</groupId><artifactId>graphframes</artifactId><version>0.8.2-spark3.2-s_2.12</version> |
| SBT 项目 | build.sbt | libraryDependencies += "graphframes" % "graphframes" % "0.8.2-spark3.2-s_2.12" |
配置完成后,在代码中通过 from graphframes import GraphFrame(Python)或 import org.graphframes.GraphFrame(Scala)导入即可使用。
3.2 创建顶点 DataFrame 与边 DataFrame
GraphFrame 的核心输入是两个 DataFrame:顶点 DataFrame 必须包含名为 id 的列;边 DataFrame 必须包含 src 和 dst 两列,分别表示边的起点和终点 ID。其他列作为顶点或边的属性自动保留。
3.2.1 顶点 DataFrame 示例
from pyspark.sql import SparkSession
from graphframes import GraphFrame
spark = SparkSession.builder.appName("GraphFramesDemo").getOrCreate()
# 顶点 DataFrame:必须包含 "id" 列
vertices = spark.createDataFrame([
("1", "Alice", 34),
("2", "Bob", 36),
("3", "Charlie", 30),
("4", "David", 29),
("5", "Eve", 32)
], ["id", "name", "age"])
vertices.show()
+---+-------+---+
| id| name|age|
+---+-------+---+
| 1| Alice| 34|
| 2| Bob| 36|
| 3|Charlie| 30|
| 4| David| 29|
| 5| Eve| 32|
+---+-------+---+
3.2.2 边 DataFrame 示例
# 边 DataFrame:必须包含 "src" 和 "dst" 列
edges = spark.createDataFrame([
("1", "2", "friend"),
("1", "3", "friend"),
("2", "3", "friend"),
("3", "4", "follow"),
("4", "5", "follow"),
("5", "1", "follow")
], ["src", "dst", "relationship"])
edges.show()
+---+---+------------+
|src|dst|relationship|
+---+---+------------+
| 1| 2| friend|
| 1| 3| friend|
| 2| 3| friend|
| 3| 4| follow|
| 4| 5| follow|
| 5| 1| follow|
+---+---+------------+
3.2.3 构建 GraphFrame 对象
g = GraphFrame(vertices, edges)
print(f"GraphFrame 构建完成:顶点数 = {g.vertices.count()}, 边数 = {g.edges.count()}")
3.3 图的基本属性查询
GraphFrame 提供了丰富的属性查询接口,无需编写复杂 SQL 即可获取图的宏观统计信息。
3.3.1 顶点数与边数
num_vertices = g.vertices.count()
num_edges = g.edges.count()
print(f"顶点数: {num_vertices}")
print(f"边数: {num_edges}")
顶点数: 5
边数: 6
3.3.2 度数分布(入度、出度、总度数)
GraphFrame 的 degrees、inDegrees、outDegrees 属性直接返回 DataFrame,包含每个顶点的度数统计。
# 总度数
g.degrees.show()
# 入度
g.inDegrees.show()
# 出度
g.outDegrees.show()
+---+------+
| id|degree|
+---+------+
| 1| 3|
| 2| 2|
| 3| 3|
| 4| 2|
| 5| 2|
+---+------+
+---+--------+
| id|inDegree|
+---+--------+
| 1| 1|
| 2| 1|
| 3| 2|
| 4| 1|
| 5| 1|
+---+--------+
+---+---------+
| id| outDegree|
+---+---------+
| 1| 2|
| 2| 1|
| 3| 1|
| 4| 1|
| 5| 1|
+---+---------+
3.3.3 度数分布统计(聚合分析)
from pyspark.sql.functions import desc
# 按度数分组统计顶点数量
degree_distribution = g.degrees.groupBy("degree").count().orderBy(desc("degree"))
degree_distribution.show()
+------+-----+
|degree|count|
+------+-----+
| 3| 2|
| 2| 3|
+------+-----+
该结果表示:度数为 3 的顶点有 2 个(Alice 和 Charlie),度数为 2 的顶点有 3 个(Bob、David、Eve)。
3.4 图结构可视化:顶点与边关系
下图展示了当前示例图的拓扑结构,包含 5 个顶点和 6 条有向边,边标签表示关系类型。
3.5 属性查询进阶:过滤与投影
由于顶点和边本身就是 DataFrame,可以直接使用 DataFrame 的 filter、select、groupBy 等算子进行灵活查询。
# 查询年龄大于 30 的顶点
g.vertices.filter("age > 30").show()
# 查询所有 "friend" 关系的边
g.edges.filter("relationship = 'friend'").show()
# 统计每种关系类型的边数
g.edges.groupBy("relationship").count().show()
+---+-----+---+
| id| name|age|
+---+-----+---+
| 1|Alice| 34|
| 2| Bob| 36|
| 5| Eve| 32|
+---+-----+---+
+---+---+------------+
|src|dst|relationship|
+---+---+------------+
| 1| 2| friend|
| 1| 3| friend|
| 2| 3| friend|
+---+---+------------+
+------------+-----+
|relationship|count|
+------------+-----+
| follow| 3|
| friend| 3|
+------------+-----+
degrees、inDegrees、outDegrees 属性在调用时会触发一次 Spark 作业(Action)。如果图规模极大(亿级边),频繁调用度数属性会导致多次 Shuffle。建议在需要度数统计时一次性计算并缓存结果 DataFrame。
3.6 本章小结
通过本章学习,你已掌握:
- GraphFrames 的 Maven / SBT / Spark Shell 安装配置方法
- 顶点 DataFrame 与边 DataFrame 的创建规范(id / src / dst 列约束)
- GraphFrame 对象的构建与基本属性查询(顶点数、边数、度数分布)
- 利用 DataFrame 算子对图属性进行过滤、分组与统计