web-dev-qa-db-ja.com

JAVAを使用してSpark DataFrameでUDFを呼び出すにはどうすればよいですか?

here と同様の質問ですが、そこにコメントするのに十分なポイントがありません。

最新のSpark documentation によると、udfは2つの異なる方法で使用できます。1つはSQLで、もう1つはDataFrameで使用できます。 sqlでudfを使用する方法について説明しますが、DataFrameでudfを直接使用する方法を見つけることができませんでした。

O.p.が提供するソリューション上記のリンクの質問では、__callUDF()__を使用します。これは__deprecated__であり、Spark 2.0に従ってSpark= = Java APIドキュメント。そこには、次のように書かれています。

「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?
_
14
Kai

Spark> = 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();

スパーク<2.3

UDFが有用であり、単純なgetItem呼び出しで置き換えることができないと仮定した場合でも、その署名は正しくありません。配列の列は、Scala WrappedArray not plain Java配列なので、署名を調整する必要があります。

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();
22
zero323