与here类似的问题,但没有足够的观点在那里发表评论。
根据最新的Spark documentation,udf
可以以两种不同的方式使用,一种使用SQL,另一种使用DataFrame。我找到了多个如何将udf
与sql一起使用的示例,但未能找到有关如何直接在DataFrame上使用udf
的任何示例。
o.p.提供的解决方案在上面链接的问题上使用__callUDF()__
_deprecated_
,并将根据Spark Java API文档在Spark 2.0中删除。在那里,它说:
“因为它与udf()”
是多余的
所以这意味着我应该可以使用__udf()__
来调用我的udf
,但我无法弄清楚如何做到这一点。我没有偶然发现任何说明Java-Spark程序语法的内容。我错过了什么?
import org.apache.spark.sql.api.java.UDF1;
.
.
UDF1 mode = new UDF1<String[], String>() {
public String call(final String[] types) throws Exception {
return types[0];
}
};
sqlContext.udf().register("mode", mode, DataTypes.StringType);
df.???????? how do I call my udf (mode) on a given column of my DataFrame df?
答案 0 :(得分:20)
Spark&gt; = 2.3
可以直接调用Scala风格的udf
:
import static org.apache.spark.sql.functions.*;
import org.apache.spark.sql.expressions.UserDefinedFunction;
UserDefinedFunction mode = udf(
(Seq<String> ss) -> ss.headOption(), DataTypes.StringType
);
df.select(mode.apply(col("vs"))).show();
Spark&lt; 2.3 强>
即使我们假设您的UDF很有用且无法用简单的getItem
调用替换它,它的签名也不正确。使用Scala WrappedArray
而不是普通的Java Arrays公开数组列,因此您必须调整签名:
UDF1 mode = new UDF1<Seq<String>, String>() {
public String call(final Seq<String> types) throws Exception {
return types.headOption();
}
};
如果UDF已经注册:
sqlContext.udf().register("mode", mode, DataTypes.StringType);
您只需使用callUDF
(这是1.5中引入的新功能)按名称调用它:
df.select(callUDF("mode", col("vs"))).show();
您也可以在selectExprs
:
df.selectExpr("mode(vs)").show();