//Your supplied code fits nicely into this function
def castOnce(df: DataFrame, colName: String, typeName: String): DataFrame = {
val colsCasted = df.columns.map{
case colName => df(colName).cast(typeName).as(colName)
case other => df(other)
}
df.select(colsCasted:_ *)
}
def castMany(df: DataFrame, colNames: Array[String], typeNames: Array[String]): DataFrame = {
assert(colNames.length == typeNames.length, "The lengths are different")
val colsWithTypes: Array[(String, String)] = colNames.zip(typeNames)
colsWithTypes.foldLeft(df)((cAndType, newDf) => castOnce(newDf, cAndType._1, cAndType._2))
}
當你有,你只需要多次適用於摺疊往往是你想要的東西同樣的事情的功能。 上面的代碼將兩個數組拉到一起,將它們合併爲一個。 然後它遍歷這個列表,每次應用你的函數到數據框,然後將下一對應用到結果數據框等。
根據你的編輯,我填寫了上面的函數。我沒有編譯器,所以我不能100%確定它的正確性。寫完後,我還在質疑我原來的做法。以下是我相信的一種更好的方式,但我將離開前一個參考。
def(df: DataFrame, colNames: Array[String], typeNames: Array[String]): DataFrame = {
assert(colNames.length == typeNames.length, "The lengths are different")
val nameToType: Map[String, String] = colNames.zip(typeNames).toMap
val newCols= df.columns.map{dfCol =>
nameToType.get(dfCol).map{newType =>
df(dfCol).cast(newType).as(dfCol)
}.getOrElse(df(dfCol))
}
df.select(newCols:_ *)
}
上面的代碼創建一個列名到所需類型的映射。 然後,在數據框的foreach列中,它看起來是Map中的類型。 如果類型存在,我們將該列轉換爲該新類型。如果該列不存在於Map中,那麼我們直接默認從DataFrame中的列。
然後我們從DataFrame中選擇這些列
當你說你的函數需要兩個數組。第一列名稱是否轉到其他數組中的第一個類型。所以他們總是有相同的長度? –
是的,長度一樣!否則會發生錯誤! – Alessandro