如何在spark中遍历数据集列?

时间:2018-01-12 09:49:40

标签: scala apache-spark spark-dataframe apache-spark-dataset

我想在scala中更改spark数据集的所有列架构; Sudo代码是这样的:

   val mydataset  =...
    for (col_t <- mydataset.columns) {
        if (col_t.name.startsWith("AA")) col_t.nullable=true; 
        if (col_t.name.startsWith("BB")) col_t.name+="CC"; 
    }

它应该根据标准更新每个(或所有)的列名和可空属性。

2 个答案:

答案 0 :(得分:1)

您可以使用df.schema获取数据框的当前架构,在其上进行映射,应用条件并将其应用于原始数据框之上。

import org.apache.spark.sql.types._

val newSchema = df.schema.map{ case StructField(name, datatype, nullable, metadata) =>
    if (name.startsWith("AA") ) StructField(name, datatype, true, metadata)
    if (name.startsWith("BB") ) StructField(name+"CC" , datatype, true, metadata)
    // more conditions here
}

这将返回List[StructField]

将其应用于原始数据框(df):

val newDf = spark.createDataFrame(df.rdd, StructType(newSchema) )

答案 1 :(得分:0)

您必须使用df.schema来确保实现此目的。

伪代码如下。

import org.apache.spark.sql.types.{ StructField, StructType }
import org.apache.spark.sql.{ DataFrame, SQLContext }

val newSchema = StructType(df.schema.map {
      case StructField(c, t, _, m) if c.equals(cn) && cn.startsWith("AA") => StructField(c, t, nullable = true, m)
      case StructField(c, t, _, m) if c.equals(cn) && cn.startsWith("BB") => StructField(c + "CC", t, nullable = nullable, m)
      case y: StructField => y
    })
val newDf = df.sqlContext.createDataFrame(df.rdd, newSchema)

希望,这有帮助。