Spark sql 中row的用法
在 Apache Spark 中,Row
是一个表示一行数据的类。它是 Spark SQL 中 DataFrame
或 Dataset
的基本数据单元。每一行数据都由一个 Row
对象表示,而 Row
对象中的每个字段对应数据的一个列。
Row
的用法
Row
对象通常用于以下场景:
-
创建数据:当你手动创建数据时,可以使用
Row
对象来表示每一行数据。 -
访问数据:当你从
DataFrame
或Dataset
中提取数据时,每一行数据都是一个Row
对象。
示例代码解析
在之前的示例中,Row
的用法如下:
val data = Seq(
Row("Alice", 25, "New York"),
Row("Bob", 30, "San Francisco"),
Row("Charlie", null, "Los Angeles")
)
1. 创建 Row
对象
-
每一行数据通过
Row(...)
创建。 -
Row
的参数顺序与模式(StructType
)中定义的字段顺序一致。 -
例如:
-
Row("Alice", 25, "New York")
表示一行数据,其中:-
第一个字段是
"Alice"
(对应name
列)。 -
第二个字段是
25
(对应age
列)。 -
第三个字段是
"New York"
(对应city
列)。
-
-
2. Row
的特点
-
Row
是一个通用的容器,可以存储不同类型的数据(如字符串、整数、布尔值等)。 -
如果某个字段没有值,可以用
null
表示(例如Row("Charlie", null, "Los Angeles")
中的age
字段)。
访问 Row
中的数据
当你从 DataFrame
或 Dataset
中提取数据时,每一行都是一个 Row
对象。你可以通过以下方式访问 Row
中的数据:
1. 通过索引访问
-
使用
row.getInt(index)
、row.getString(index)
等方法,根据字段的类型和索引访问数据。 -
索引从
0
开始。
val firstRow = df.head() // 获取第一行数据
val name = firstRow.getString(0) // 访问第一个字段(name)
val age = firstRow.getInt(1) // 访问第二个字段(age)
val city = firstRow.getString(2) // 访问第三个字段(city)
2. 通过字段名访问
-
使用
row.getAs[T](fieldName)
方法,根据字段名访问数据。 -
需要指定字段的类型
T
。
val name = firstRow.getAs[String]("name") // 访问 name 字段
val age = firstRow.getAs[Int]("age") // 访问 age 字段
val city = firstRow.getAs[String]("city") // 访问 city 字段
3. 转换为集合
-
使用
row.toSeq
将Row
转换为一个序列(Seq
),方便遍历。
val rowData = firstRow.toSeq // 转换为 Seq[Any]
rowData.foreach(println) // 打印每一列的值
完整示例
以下是一个完整的示例,展示如何创建 Row
对象并访问其中的数据:
import org.apache.spark.sql.{Row, SparkSession}
import org.apache.spark.sql.types.{StructType, StructField, StringType, IntegerType}
// 创建 SparkSession
val spark = SparkSession.builder()
.appName("Row Example")
.master("local[*]")
.getOrCreate()
// 定义模式
val schema = new StructType()
.add(StructField("name", StringType, nullable = false))
.add(StructField("age", IntegerType, nullable = true))
.add(StructField("city", StringType, nullable = true))
// 创建数据
val data = Seq(
Row("Alice", 25, "New York"),
Row("Bob", 30, "San Francisco"),
Row("Charlie", null, "Los Angeles")
)
// 创建 DataFrame
val df = spark.createDataFrame(spark.sparkContext.parallelize(data), schema)
// 访问第一行数据
val firstRow = df.head()
// 通过索引访问
println(s"Name: ${firstRow.getString(0)}") // Name: Alice
println(s"Age: ${firstRow.getInt(1)}") // Age: 25
println(s"City: ${firstRow.getString(2)}") // City: New York
// 通过字段名访问
println(s"Name: ${firstRow.getAs[String]("name")}") // Name: Alice
println(s"Age: ${firstRow.getAs[Int]("age")}") // Age: 25
println(s"City: ${firstRow.getAs[String]("city")}") // City: New York
// 转换为 Seq 并打印
val rowData = firstRow.toSeq
rowData.foreach(println) // 打印:Alice, 25, New York
总结
-
Row
是 Spark 中表示一行数据的类。 -
可以通过索引或字段名访问
Row
中的数据。 -
Row
是创建DataFrame
或Dataset
时的重要组件,用于表示每一行数据。