Вот рекурсивный метод, который пересматривает схему DataFrame, переименовывая через replaceAll
любые столбцы, имя которых состоит из подстроки, подлежащей замене:
import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._
def renameAllColumns(schema: StructType, from: String, to:String): StructType = {
def recurRename(schema: StructType, from: String, to:String): Seq[StructField] =
schema.fields.map{
case StructField(name, dtype: StructType, nullable, meta) =>
StructField(name.replaceAll(from, to), StructType(recurRename(dtype, from, to)), nullable, meta)
case StructField(name, dtype, nullable, meta) =>
StructField(name.replaceAll(from, to), dtype, nullable, meta)
}
StructType(recurRename(schema, from, to))
}
Тестирование метода на образце DataFrame с вложенным Структура:
case class M(i: Int, `p:q`: String)
case class N(j: Int, m: M)
val df = Seq(
(1, "a", N(7, M(11, "x"))),
(2, "b", N(8, M(21, "y"))),
(3, "c", N(9, M(31, "z")))
).toDF("c1", "c2:0", "c3")
df.printSchema
// root
// |-- c1: integer (nullable = false)
// |-- c2:0: string (nullable = true)
// |-- c3: struct (nullable = true)
// | |-- j: integer (nullable = false)
// | |-- m: struct (nullable = true)
// | | |-- i: integer (nullable = false)
// | | |-- p:q: string (nullable = true)
val rdd = df.rdd
val newSchema = renameAllColumns(df.schema, ":", "_")
spark.createDataFrame(rdd, newSchema).printSchema
// root
// |-- c1: integer (nullable = false)
// |-- c2_0: string (nullable = true)
// |-- c3: struct (nullable = true)
// | |-- j: integer (nullable = false)
// | |-- m: struct (nullable = true)
// | | |-- i: integer (nullable = false)
// | | |-- p_q: string (nullable = true)
Обратите внимание, что поскольку метод replaceAll
понимает шаблон Regex, можно применить метод, чтобы обрезать имя столбца, начиная с char ':', например:
val newSchema = renameAllColumns(df.schema, """:.*""", "")
spark.createDataFrame(rdd, newSchema).printSchema
// root
// |-- c1: integer (nullable = false)
// |-- c2: string (nullable = true)
// |-- c3: struct (nullable = true)
// | |-- j: integer (nullable = false)
// | |-- m: struct (nullable = true)
// | | |-- i: integer (nullable = false)
// | | |-- p: string (nullable = true)