Spark sql 中row的用法

发布于:2025-03-17 ⋅ 阅读:(13) ⋅ 点赞:(0)

在 Apache Spark 中,Row 是一个表示一行数据的类。它是 Spark SQL 中 DataFrame 或 Dataset 的基本数据单元。每一行数据都由一个 Row 对象表示,而 Row 对象中的每个字段对应数据的一个列。

Row 的用法

Row 对象通常用于以下场景:

  1. 创建数据:当你手动创建数据时,可以使用 Row 对象来表示每一行数据。

  2. 访问数据:当你从 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 时的重要组件,用于表示每一行数据。