为了能够使用我的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
答案 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)
并使用该模式重新读取数据框