使用空/空字段值创建新的Dataframe

ssh*_*off 25 scala dataframe apache-spark apache-spark-sql

我正在从现有数据框架创建一个新的Dataframe,但需要在这个新DF中添加新列(下面代码中的"field1").我该怎么办?工作示例代码示例将不胜感激.

val edwDf = omniDataFrame 
  .withColumn("field1", callUDF((value: String) => None)) 
  .withColumn("field2",
    callUdf("devicetypeUDF", (omniDataFrame.col("some_field_in_old_df")))) 

edwDf
  .select("field1", "field2")
  .save("odsoutdatafldr", "com.databricks.spark.csv"); 
Run Code Online (Sandbox Code Playgroud)

zer*_*323 70

可以使用lit(null):

import org.apache.spark.sql.functions.{lit, udf}

case class Record(foo: Int, bar: String)
val df = Seq(Record(1, "foo"), Record(2, "bar")).toDF

val dfWithFoobar = df.withColumn("foobar", lit(null: String))
Run Code Online (Sandbox Code Playgroud)

这里的一个问题是列类型是null:

scala> dfWithFoobar.printSchema
root
 |-- foo: integer (nullable = false)
 |-- bar: string (nullable = true)
 |-- foobar: null (nullable = true)
Run Code Online (Sandbox Code Playgroud)

它并没有被csv作者保留.如果这是一个很难的要求,你可以将列转换为特定类型(比如说String)DataType

import org.apache.spark.sql.types.StringType

df.withColumn("foobar", lit(null).cast(StringType))
Run Code Online (Sandbox Code Playgroud)

或字符串描述

df.withColumn("foobar", lit(null).cast("string"))
Run Code Online (Sandbox Code Playgroud)

或使用这样的UDF:

val getNull = udf(() => None: Option[String]) // Or some other type

df.withColumn("foobar", getNull()).printSchema
root
 |-- foo: integer (nullable = false)
 |-- bar: string (nullable = true)
 |-- foobar: string (nullable = true)
Run Code Online (Sandbox Code Playgroud)

可以在此处找到Python等效项:添加一个空列以激活DataFrame

  • @ zero323,感谢分享这个,非常有帮助.请参阅我的编辑以获得其他类型的支持. (2认同)

san*_*4ka 9

只是为了扩展@zero323 提供的完美答案,这里有一个可以从 Spark 2.2.0 开始使用的解决方案。

import org.apache.spark.sql.functions.typedLit

df.withColumn("foobar", typedLit[Option[String]](None)).printSchema
root
 |-- foo: integer (nullable = false)
 |-- bar: string (nullable = true)
 |-- foobar: string (nullable = true)

Run Code Online (Sandbox Code Playgroud)

它类似于第三个解决方案,但不使用任何 UDF。