当前位置: 首页 > article >正文

Spark 中创建 DataFrame 的2种方式对比

spark.createDataFrame(data).toDF("name", "age")

spark.createDataFrame(spark.sparkContext.parallelize(data), schema)

创建df的方式有什么区别?

在 Spark 中,创建 DataFrame 的方式有多种,其中两种常见的方式是:

  1. spark.createDataFrame(data).toDF("name", "age")

  2. spark.createDataFrame(spark.sparkContext.parallelize(data), schema)

这两种方式的主要区别在于 数据来源 和 模式(Schema)的定义方式。下面详细分析它们的区别和适用场景。


1. spark.createDataFrame(data).toDF("name", "age")

特点
  • 数据来源data 是一个本地集合(如 Seq 或 List),Spark 会将其并行化为分布式数据集(RDD)。

  • 模式推断:Spark 会自动推断数据的模式(Schema),并根据列的顺序为列命名。

  • 列名指定:通过 toDF("name", "age") 显式指定列名。

示例
import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder()
  .appName("DataFrame Example")
  .master("local[*]")
  .getOrCreate()

// 数据是一个本地集合
val data = Seq(("Alice", 25), ("Bob", 30), ("Charlie", 35))

// 创建 DataFrame,并指定列名
val df = spark.createDataFrame(data).toDF("name", "age")

df.show()

输出:

+-------+---+
|   name|age|
+-------+---+
|  Alice| 25|
|    Bob| 30|
|Charlie| 35|
+-------+---+
适用场景
  • 数据量较小,可以直接在本地集合中定义。

  • 不需要显式定义复杂的模式(Schema)。

  • 列名可以通过 toDF 简单指定。


2. spark.createDataFrame(spark.sparkContext.parallelize(data), schema)

特点
  • 数据来源data 是一个本地集合,通过 spark.sparkContext.parallelize(data) 将其显式转换为 RDD。

  • 模式定义:需要显式定义一个模式(StructType),指定每列的名称和数据类型。

  • 灵活性:适合处理复杂的数据结构(如嵌套结构体)。

示例
import org.apache.spark.sql.{SparkSession, Row}
import org.apache.spark.sql.types._

val spark = SparkSession.builder()
  .appName("DataFrame Example")
  .master("local[*]")
  .getOrCreate()

// 数据是一个本地集合,每个元素是一个 Row 对象
val data = Seq(
  Row("Alice", 25),
  Row("Bob", 30),
  Row("Charlie", 35)
)

// 定义模式
val schema = new StructType()
  .add(StructField("name", StringType, nullable = false))
  .add(StructField("age", IntegerType, nullable = false))

// 创建 DataFrame
val df = spark.createDataFrame(spark.sparkContext.parallelize(data), schema)

df.show()

输出:

+-------+---+
|   name|age|
+-------+---+
|  Alice| 25|
|    Bob| 30|
|Charlie| 35|
+-------+---+
适用场景
  • 数据量较大,需要显式并行化为 RDD。

  • 数据结构复杂,需要显式定义模式(Schema)。

  • 需要更精确地控制列的数据类型和是否允许为空。


3. 主要区别

特性spark.createDataFrame(data).toDF("name", "age")spark.createDataFrame(spark.sparkContext.parallelize(data), schema)
数据来源本地集合(自动并行化为 RDD)本地集合(显式并行化为 RDD)
模式定义自动推断模式需要显式定义模式(StructType
列名指定通过 toDF 指定列名在模式中定义列名
数据类型控制自动推断数据类型可以显式指定每列的数据类型
是否允许为空默认允许为空可以显式指定是否允许为空
适用场景简单数据结构,数据量较小复杂数据结构,数据量较大

4. 选择哪种方式?

  • 使用 spark.createDataFrame(data).toDF("name", "age") 的情况

    • 数据量较小,可以直接在本地集合中定义。

    • 数据结构简单,不需要显式定义模式。

    • 列名可以通过 toDF 简单指定。

  • 使用 spark.createDataFrame(spark.sparkContext.parallelize(data), schema) 的情况

    • 数据量较大,需要显式并行化为 RDD。

    • 数据结构复杂,需要显式定义模式。

    • 需要精确控制列的数据类型和是否允许为空。


5. 复杂数据结构示例

如果需要处理嵌套结构体(如数组或结构体),推荐使用显式定义模式的方式。

示例:嵌套结构体
import org.apache.spark.sql.{SparkSession, Row}
import org.apache.spark.sql.types._

val spark = SparkSession.builder()
  .appName("Nested DataFrame Example")
  .master("local[*]")
  .getOrCreate()

// 数据是一个本地集合,包含嵌套结构
val data = Seq(
  Row("Alice", Row("Java", 5)),
  Row("Bob", Row("Python", 4))
)

// 定义模式
val schema = new StructType()
  .add(StructField("name", StringType, nullable = false))
  .add(StructField("skill", new StructType()
    .add(StructField("name", StringType, nullable = false))
    .add(StructField("level", IntegerType, nullable = false))
  ))

// 创建 DataFrame
val df = spark.createDataFrame(spark.sparkContext.parallelize(data), schema)

df.printSchema()
df.show()

输出:

root
 |-- name: string (nullable = false)
 |-- skill: struct (nullable = false)
 |    |-- name: string (nullable = false)
 |    |-- level: integer (nullable = false)

+-----+----------+
| name|     skill|
+-----+----------+
|Alice| [Java, 5]|
|  Bob|[Python, 4]|
+-----+----------+

总结

  • spark.createDataFrame(data).toDF("name", "age"):适合简单场景,自动推断模式。

  • spark.createDataFrame(spark.sparkContext.parallelize(data), schema):适合复杂场景,显式定义模式。

根据数据结构和需求选择合适的方式即可!如果还有其他问题,欢迎继续提问。


http://www.kler.cn/a/586711.html

相关文章:

  • 【最后203篇系列】015 几种消息队列的思考
  • docker后台运行,便于后期用命令行进入它的终端
  • 【vscode-03】AUTOSAR CP 插件配置
  • DataWhale 速通AI编程开发:(进阶篇)第3章 提示词(Prompts)配置项
  • AI与人的智能,改变一生的思维模型【7】易得性偏差
  • 空调acwing二进制差分
  • C++移动语义与右值引用:从理论到实践的深度解析引言
  • python:数据类构建器
  • 《DeepSeek深度使用教程:开启智能交互新体验》Deepseek深度使用教程
  • 【大模型基础_毛玉仁】2.4 基于 Encoder-Decoder 架构的大语言模型
  • AtCoder Beginner Contest 003(A - 社の給料、B -トランプ、C -プログラミング講座、D - 社の冬 )题目讲解
  • 【PHP】新版本特性记录(持续更新)
  • java 的标记接口RandomAccess使用方法
  • vulnhub靶场之stapler靶机
  • MIDI,AI 3D场景生成技术
  • Audacity 技术浅析(一)
  • [CISSP] [3] 人员安全与社会工程
  • 原生微信小程序实现导航漫游(Tour)
  • 农作物病害数据集
  • 性能优化:javascript 如何检测并处理页面卡顿