PySpark ligne sage fonction de la composition
Comme un exemple simplifié, j'ai un dataframe "df" avec des colonnes "col1,col2" et je veux calculer une ligne sage maximum après application d'une fonction à chaque colonne :
def f(x):
return (x+1)
max_udf=udf(lambda x,y: max(x,y), IntegerType())
f_udf=udf(f, IntegerType())
df2=df.withColumn("result", max_udf(f_udf(df.col1),f_udf(df.col2)))
Donc si df:
col1 col2
1 2
3 0
Puis
df2:
col1 col2 result
1 2 3
3 0 4
Le ci-dessus ne semble pas fonctionner et produit "Impossible d'évaluer l'expression: PythonUDF#f..."
Je suis tout à fait positive "f_udf" fonctionne très bien sur ma table, et le principal problème est avec le max_udf.
Sans créer des colonnes supplémentaires ou de l'aide de la base map/reduce, est-il un moyen pour faire le dessus entièrement en utilisant dataframes et de l'udf? Comment dois-je modifier "max_udf"?
J'ai aussi essayé:
max_udf=udf(max, IntegerType())
qui produit la même erreur.
J'ai également confirmé que les travaux suivants:
df2=(df.withColumn("temp1", f_udf(df.col1))
.withColumn("temp2", f_udf(df.col2))
df2=df2.withColumn("result", max_udf(df2.temp1,df2.temp2))
Pourquoi est-ce que je peux pas faire en une seule fois?
Je voudrais voir une réponse qui généralise à toute la fonction "f_udf" et "max_udf."
Vous devez vous connecter pour publier un commentaire.
J'ai eu le même problème et trouvé la solution dans la réponse à la cette question stackoverflow
Pour passer plusieurs colonnes ou une ligne entière à un UDF utiliser un struct:
retourne:
UserDefinedFunction est jeter de l'erreur, tout en acceptant des fonctions définies par l'utilisateur comme leurs arguments.
Vous pouvez modifier le max_udf comme ci-dessous pour le faire fonctionner.
Ou
Note:
La deuxième approche est valide si et seulement si les fonctions internes (ici
f_udf
) générer des expressions SQL valides.Cela fonctionne ici, car
f_udf(df.col1)
etf_udf(df.col2)
sont évaluées commeColumn<b'(col1 + 1)'>
etColumn<b'(col2 + 1)'>
respectivement, avant d'être passé àmax_udf
. Il ne serait pas travailler avec une fonction arbitraire.Ça ne marcherait pas si nous essayons par exemple quelque chose comme ceci: