web-dev-qa-db-ja.com

Spark Dataframeの関数で新しい列を作成します

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を使用するよりも良い/別の方法がありますか?

ご協力いただきありがとうございます。

36
J Calbreath

スキーマに「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は列を追加する正しい方法だと思います

53
yjshen

列のudfおよびserializationのオーバーヘッドのため、deserialization関数をできるだけ定義しないようにする必要があります。

以下のように、単純なwhen spark関数を使用してソリューションを実現できます。

val myDF = sqlContext.parquetFile("hdfs:/to/my/file.parquet")

myDF.withColumn("Code", when(myDF("Amt") < 100, "Little").otherwise("Big"))
11
Ramesh Maharjan

これを行う別の方法:任意の関数を作成できますが、上記のエラーに従って、関数を変数として定義する必要があります

例:

val coder = udf((myAmt:Integer) => {
  if (myAmt > 100) "Little"
  else "Big"
})

これで、このステートメントは完全に機能します。

myDF.withColumn("Code", coder(myDF("Amt")))
1
imran