Sparkの新しいデータフレームAPIを理解しようとしています。一歩前進したように思えますが、非常に単純なことを実行するのに苦労しています。 「ID」と「金額」の2列のデータフレームがあります。一般的な例として、「Amt」の値に基づいてコードを返す「code」という新しい列を返したいとします。私はこのような機能を書くことができます:
def coder(myAmt:Integer):String {
if (myAmt > 100) "Little"
else "Big"
}
このように使用しようとすると:
val myDF = sqlContext.parquetFile("hdfs:/to/my/file.parquet")
myDF.withColumn("Code", coder(myDF("Amt")))
型の不一致エラーが発生します
found : org.Apache.spark.sql.Column
required: Integer
関数の入力タイプをorg.Apache.spark.sql.Columnに変更しようとしましたが、ifステートメントにブール値が必要なため、関数のコンパイル時にwrrorを取得し始めました。
私はこれを間違っていますか? withColumnを使用するよりも良い/別の方法がありますか?
ご協力いただきありがとうございます。
スキーマに「Amt」列があるとします。
import org.Apache.spark.sql.functions._
val myDF = sqlContext.parquetFile("hdfs:/to/my/file.parquet")
val coder: (Int => String) = (arg: Int) => {if (arg < 100) "little" else "big"}
val sqlfunc = udf(coder)
myDF.withColumn("Code", sqlfunc(col("Amt")))
WithColumnは列を追加する正しい方法だと思います
列のudf
およびserialization
のオーバーヘッドのため、deserialization
関数をできるだけ定義しないようにする必要があります。
以下のように、単純なwhen
spark関数を使用してソリューションを実現できます。
val myDF = sqlContext.parquetFile("hdfs:/to/my/file.parquet")
myDF.withColumn("Code", when(myDF("Amt") < 100, "Little").otherwise("Big"))
これを行う別の方法:任意の関数を作成できますが、上記のエラーに従って、関数を変数として定義する必要があります
例:
val coder = udf((myAmt:Integer) => {
if (myAmt > 100) "Little"
else "Big"
})
これで、このステートメントは完全に機能します。
myDF.withColumn("Code", coder(myDF("Amt")))