基于列的条件更改 Spark DataFrame 的数据类型

4

我有一个名为df1的Spark DataFrame,它大约有1000个String类型的列。现在我想根据列名的条件将df1的列类型从字符串转换为其他类型,例如double、int等等。例如,假设df1仅有三个字符串类型的列。

df1.printSchema

col1_term1: String
col2_term2: String 
col3_term3: String

更改列类型的条件是,如果列名包含term1,则将其更改为int,如果列名包含term2,则将其更改为double等等。我对Spark不熟悉。

2个回答

8
你可以简单地映射列,并根据列名将列转换为适当的数据类型:
import org.apache.spark.sql.types._

val df = Seq(("1", "2", "3"), ("2", "3", "4")).toDF("col1_term1", "col2_term2", "col3_term3")

val cols = df.columns.map(x => {
    if (x.contains("term1")) col(x).cast(IntegerType) 
    else if (x.contains("term2")) col(x).cast(DoubleType) 
    else col(x)
})

df.select(cols: _*).printSchema
root
 |-- col1_term1: integer (nullable = true)
 |-- col2_term2: double (nullable = true)
 |-- col3_term3: string (nullable = true)

嗨@Psidom,我尝试了你的方法,似乎它改变了类型,但也改变了名称。我得到的printSchema类似于cast(col1_term1 as integer): integer (nullable = true)。 - Umesh K
你使用的是哪个Spark版本?我在Spark 2+中没有得到预期的行为。你可以尝试使用alias,例如col(x).cast(IntegerType).alias(x) - Psidom

1
虽然这种解决方案与@Psidom提出的解决方案没有任何不同,但您也可以像这样使用一些Scala的语法糖syntactic-sugar
val modifiedDf: DataFrame = originalDf.columns.foldLeft[DataFrame](originalDf) { (tmpDf: DataFrame, colName: String) =>
  if (colName.contains("term1")) tmpDf.withColumn(colName, tmpDf(colName).cast(IntegerType))
  else if (colName.contains("term2")) tmpDf.withColumn(colName, tmpDf(colName).cast(DoubleType))
  else tmpDf
}

如果你有一个包含StructTypes和ArrayStructs的嵌套数据框,你会怎么做?在我的情况下,我需要处理一个深度嵌套的模式,并且我需要将每一列都转换为ArrayStruct,其中匹配列表中特定列的StructType。 - ruifgmonteiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接