mah*_*hdi 5 scala dataframe apache-spark apache-spark-sql
有没有办法使用 StructType 来转换数据帧的所有值?
让我用一个例子来解释我的问题:
假设我们从文件读取后获得了一个数据帧(我提供了生成此数据帧的代码,但在我的现实世界项目中,我在从文件读取后获得了此数据帧):
import org.apache.spark.sql.{Row, SparkSession}
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
import spark.implicits._
val rows1 = Seq(
Row("1", Row("a", "b"), "8.00", Row("1","2")),
Row("2", Row("c", "d"), "9.00", Row("3","4"))
)
val rows1Rdd = spark.sparkContext.parallelize(rows1, 4)
val schema1 = StructType(
Seq(
StructField("id", StringType, true),
StructField("s1", StructType(
Seq(
StructField("x", StringType, true),
StructField("y", StringType, true)
)
), true),
StructField("d", StringType, true),
StructField("s2", StructType(
Seq(
StructField("u", StringType, true),
StructField("v", StringType, true)
)
), true)
)
)
val df1 = spark.createDataFrame(rows1Rdd, schema1)
println("Schema with nested struct")
df1.printSchema()
root
|-- id: string (nullable = true)
|-- s1: struct (nullable = true)
| |-- x: string (nullable = true)
| |-- y: string (nullable = true)
|-- d: string (nullable = true)
|-- s2: struct (nullable = true)
| |-- u: string (nullable = true)
| |-- v: string (nullable = true)
Run Code Online (Sandbox Code Playgroud)
现在假设我的客户向我提供了他想要的数据的架构(这相当于读取数据帧的架构,但具有不同的数据类型(包含 StringTypes、IntegerTypes ...)):
val wantedSchema = StructType(
Seq(
StructField("id", IntegerType, true),
StructField("s1", StructType(
Seq(
StructField("x", StringType, true),
StructField("y", StringType, true)
)
), true),
StructField("d", DoubleType, true),
StructField("s2", StructType(
Seq(
StructField("u", IntegerType, true),
StructField("v", IntegerType, true)
)
), true)
)
)
Run Code Online (Sandbox Code Playgroud)
使用提供的 StructType 转换数据帧值的最佳方法是什么?
如果有一种方法可以应用于数据框,并且它通过自行转换所有值来应用新的 StructTypes,那就太好了。
PS:这是一个小型数据框,用作示例,在我的项目中,数据框包含更多行。如果它是一个只有几列的小型数据框,我可以轻松完成转换,但就我而言,我正在寻找一种智能解决方案,通过应用 StructType 来转换所有值,而无需手动转换每个列/值代码。
我将不胜感激您能提供的任何帮助,非常感谢!
经过大量研究后,这是一个按照模式转换数据帧的通用解决方案:
val castedDf = df1.selectExpr(wantedSchema.map(
field => s"CAST ( ${field.name} As ${field.dataType.sql}) ${field.name}"
): _*)
Run Code Online (Sandbox Code Playgroud)
这是投射数据框的架构:
castedDf.printSchema
root
|-- id: integer (nullable = true)
|-- s1: struct (nullable = true)
| |-- x: string (nullable = true)
| |-- y: string (nullable = true)
|-- d: double (nullable = true)
|-- s2: struct (nullable = true)
| |-- u: integer (nullable = true)
| |-- v: integer (nullable = true)
Run Code Online (Sandbox Code Playgroud)
我希望它能对某人有所帮助,我花了 5 天的时间寻找这个简单/通用的解决方案。
| 归档时间: |
|
| 查看次数: |
7245 次 |
| 最近记录: |