Comment puis-je passer des paramètres supplémentaires pour Udf Spark SQL?
Je veux analyser les colonnes de date dans un DataFrame
, et pour chaque colonne de la date de la résolution pour la date peut changer (c'est à dire 2011/01/10 => 2011 /01 si la résolution est réglée sur "Mois").
J'ai écrit le code suivant:
def convertDataFrame(dataframe: DataFrame, schema : Array[FieldDataType], resolution: Array[DateResolutionType]) : DataFrame =
{
import org.apache.spark.sql.functions._
val convertDateFunc = udf{(x:String, resolution: DateResolutionType) => SparkDateTimeConverter.convertDate(x, resolution)}
val convertDateTimeFunc = udf{(x:String, resolution: DateResolutionType) => SparkDateTimeConverter.convertDateTime(x, resolution)}
val allColNames = dataframe.columns
val allCols = allColNames.map(name => dataframe.col(name))
val mappedCols =
{
for(i <- allCols.indices) yield
{
schema(i) match
{
case FieldDataType.Date => convertDateFunc(allCols(i), resolution(i)))
case FieldDataType.DateTime => convertDateTimeFunc(allCols(i), resolution(i))
case _ => allCols(i)
}
}
}
dataframe.select(mappedCols:_*)
}}
Toutefois, il ne fonctionne pas. Il semble que je ne peux passer Column
s à l'Udf. Et je me demande si il sera très lente si je convertir le DataFrame
à RDD
et d'appliquer la fonction sur chaque ligne.
Quelqu'un sait-il la bonne solution? Merci!!!!
Vous devez vous connecter pour publier un commentaire.
Il suffit d'utiliser un peu de nourrissage:
et de l'utiliser comme suit:
Sur une note de côté, vous devriez jeter un oeil à
sql.functions.trunc
etsql.functions.date_format
. Ceux-ci devraient au moins une partie de la tâche sans l'aide de fonctions définies par l'utilisateur à tous.Note:
Spark 2.2 ou ultérieure, vous pouvez utiliser
typedLit
fonction:qui prennent en charge un large éventail de littéraux comme
Seq
ouMap
.Vous pouvez créer un littéral
Column
pour passer d'une fonction à l'aide de lalit(...)
fonction définie dansorg.apache.spark.sql.functions
Par exemple:
lit
ainsi, mais il s'avère que son rendement n'est pas aussi bonne que l'autre réponse...