Scala Spark:性能问题重命名大量列

时间:2017-02-08 08:33:21

标签: scala csv apache-spark

为了能够使用我的DataFrame的列名而不转义.我需要一个“验证”所有列名的功能 - 但我尝试过的方法都没有及时完成工作(我5分钟后就流产了。)

我正在尝试算法的数据集是golub数据集(得到它here)。这是一个2.2MB的CSV文件,有7200列。重命名所有列应该只需几秒钟

中读取CSV的代码
var dfGolub = spark.read
    .option("header", "true")
    .option("inferSchema", "true")
    .csv("golub_merged.csv")
    .drop("_c0") // drop the first column
    .repartition(numOfCores)

尝试重命名列:

 def validifyColumnnames1(df : DataFrame) : DataFrame = {
     import org.apache.spark.sql.functions.col
     val cols = df.columns
     val colsRenamed = cols.map(name => col(name).as(name.replaceAll("\\.","")))
     df.select(colsRenamed : _*)
 }


def validifyColumnnames2[T](df : Dataset[T]) : DataFrame = {
    val newColumnNames = ArrayBuffer[String]()
    for(oldCol <- df.columns) {
        newColumnNames +=  oldCol.replaceAll("\\.","")
    }
    df.toDF(newColumnNames : _*)
}

def validifyColumnnames3(df : DataFrame) : DataFrame = {
    var newDf = df
    for(col <- df.columns){
        newDf = newDf.withColumnRenamed(col,col.replaceAll("\\.",""))
    }
    newDf
}

是什么导致了这个性能问题?

设置:我在具有16个核心* 2线程和96GB RAM的计算机上以local[24]模式在Ubuntu 16.04上运行Spark 2.1.0

1 个答案:

答案 0 :(得分:4)

假设您知道类型,您可以简单地创建模式而不是推断它(推断模式成本性能,甚至可能是csv错误)。

让我们假设为简单起见,您可以使用以下文件example.csv:

A.B, A.C, A.D
a,3,1

您可以这样做:

val scehma = StructType(Seq(StructField("A_B",StringType),StructField("A_C", IntegerType), StructField("AD", IntegerType)))
val df = spark.read.option("header","true").schema(scehma).csv("example.csv")
df.show()

+---+---+---+
|A_B|A_C| AD|
+---+---+---+
|  a|  3|  1|
+---+---+---+

如果您事先不知道信息,可以像以前一样使用推断模式,那么您可以使用数据框生成模式:

val fields = for {
  x <- df.schema
} yield StructField(x.name.replaceAll("\\.",""), x.dataType, x.nullable)
val schema = StructType(fields)

并使用该模式重新读取数据框