Apache spark 如何将json中的空值字段作为数据帧中的数字加载

Apache spark 如何将json中的空值字段作为数据帧中的数字加载,apache-spark,apache-spark-sql,spark-dataframe,Apache Spark,Apache Spark Sql,Spark Dataframe,在Dataframe printschema中,一个Json字段(年龄如下)表示为null的数字作为字符串出现 输入json文件 {"AGE":null,"NAME":"abc","BATCH":190} {"AGE":null,"NAME":"abc","BATCH":190} 火花代码和输出 val df = spark.read.json("/home/white/tmp/a.json") df.printSchema() df.show() *********************

在Dataframe printschema中,一个Json字段(年龄如下)表示为null的数字作为字符串出现

输入json文件

{"AGE":null,"NAME":"abc","BATCH":190}
{"AGE":null,"NAME":"abc","BATCH":190}
火花代码和输出

val df = spark.read.json("/home/white/tmp/a.json")
df.printSchema()
df.show()

*********************
OUTPUT
*********************
root
 |-- BATCH: long (nullable = true)
 |-- AGE: string (nullable = true)
 |-- NAME: string (nullable = true)

+-----+----+----+
|BATCH|AGE|NAME|
+-----+----+----+
|  190|null| abc|
|  190|null| abc|
+-----+----+----+

我希望age是一个长的,目前我正在通过创建一个新的StructType,将age字段设置为long,并将数据帧重新创建为df.sqlContext.createDataFrame(df.rdd,newSchema)。我可以直接在spark.read.json api中完成这项工作吗?

您可以创建一个case类,并将其提供给要填充的read.json方法。这将为您提供数据集(而不是数据帧)

参考:


另一个选择是创建自己的InputReader来使用,而不是使用标准的JSON读取器。您已经在做的最后一个选择是添加额外的步骤来转换类型。

我认为最简单的方法如下:

spark.read.json("/home/white/tmp/a.json").withColumn("AGE", 'AGE.cast(LongType))
这将生成以下架构:

root
 |-- AGE: long (nullable = true)
 |-- BATCH: long (nullable = true)
 |-- NAME: string (nullable = true)
Spark对类型进行了最佳猜测,它会在JSON中看到
null
,并考虑“string”,因为
string
位于Scala对象层次结构的可空
AnyRef
一侧,而
Long
位于不可空
AnyVal
一侧。您只需要转换列,使Spark按您认为合适的方式处理数据


顺便说一句,为什么你要用
Long
而不是
Int
来表示年龄?那些人必须吃得很健康

如果您已经知道有哪些类型,我建议您使用预定义的模式来阅读

import org.apache.spark.sql.types._
val schema = StructType(List(
    StructField("AGE", IntegerType, nullable = true),
    StructField("BATCH", StringType, nullable = true),
    StructField("NAME", StringType, nullable = true)
))

spark.read.schema(schema).json("/home/white/tmp/a.json")

我应该添加如何在json中将整数值表示为null,以便spark能够理解特定字段是整数。
import org.apache.spark.sql.types._
val schema = StructType(List(
    StructField("AGE", IntegerType, nullable = true),
    StructField("BATCH", StringType, nullable = true),
    StructField("NAME", StringType, nullable = true)
))

spark.read.schema(schema).json("/home/white/tmp/a.json")