欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > Spark 中创建 DataFrame 的2种方式对比

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

2025/3/16 10:07:56 来源:https://blog.csdn.net/m0_63322122/article/details/146280949  浏览:    关键词: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.SparkSessionval 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):适合复杂场景,显式定义模式。

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词