式を使用してデータフレームに新しい列を追加します。たとえば、私はのデータフレームを持っています
+-----+----------+----------+-----+
| C1 | C2 | C3 |C4 |
+-----+----------+----------+-----+
|steak|1 |1 | 150|
|steak|2 |2 | 180|
| fish|3 |3 | 100|
+-----+----------+----------+-----+
そして、追加する必要のある新しい列がいくつかあり、式が異なる場合があり、データベースからのものであると仮定して、式「C2/C3 + C4」で新しい列C5を作成したいと思います。
これを行う良い方法はありますか?
「2 + 3 * 4」のような式がある場合、scala.tools.reflect.ToolBoxを使用して評価できます。
通常、私はdf.withColumnを使用して新しい列を追加しています。
UDFを作成する必要があるようですが、UDFにパラメーターとして列の値を渡すにはどうすればよいですか?特に、複数の式に異なる列の計算が必要な場合があります。
これは、式からexpr
を作成するColumn
を使用して実行できます。
val df = Seq((1,2)).toDF("x","y")
val myExpression = "x+y"
import org.Apache.spark.sql.functions.expr
df.withColumn("z",expr(myExpression)).show()
+---+---+---+
| x| y| z|
+---+---+---+
| 1| 2| 3|
+---+---+---+
2つのアプローチ:
import spark.implicits._ //so that you could use .toDF
val df = Seq(
("steak", 1, 1, 150),
("steak", 2, 2, 180),
("fish", 3, 3, 100)
).toDF("C1", "C2", "C3", "C4")
import org.Apache.spark.sql.functions._
// 1st approach using expr
df.withColumn("C5", expr("C2/(C3 + C4)")).show()
// 2nd approach using selectExpr
df.selectExpr("*", "(C2/(C3 + C4)) as C5").show()
+-----+---+---+---+--------------------+
| C1| C2| C3| C4| C5|
+-----+---+---+---+--------------------+
|steak| 1| 1|150|0.006622516556291391|
|steak| 2| 2|180| 0.01098901098901099|
| fish| 3| 3|100| 0.02912621359223301|
+-----+---+---+---+--------------------+
Spark 2.xでは、withColumn()
およびorg.Apache.spark.sql.functions._
を使用して、式 "C2/C3 + C4"で新しい列C5を作成できます。
val currentDf = Seq(
("steak", 1, 1, 150),
("steak", 2, 2, 180),
("fish", 3, 3, 100)
).toDF("C1", "C2", "C3", "C4")
val requiredDf = currentDf
.withColumn("C5", (col("C2")/col("C3")+col("C4")))
また、org.Apache.spark.sql.Column
を使用しても同じことができます。 (ただし、このアプローチでは、Columnオブジェクトの作成のため、org.Apache.spark.sql.functions._
を使用するよりもスペースの複雑さが若干高くなります)
val requiredDf = currentDf
.withColumn("C5", (new Column("C2")/new Column("C3")+new Column("C4")))
これは私にとって完璧に機能しました。私はSpark 2.0.2。