Json可以将单个值或多个值的数组作为属性值。例如,"A":"ae"
或"A":["ab", "cd"]
当我读取json-nd文件(每行是一个json)时,我的target属性可能只有一个值或一个相同类型值的数组。
我需要使用explode()
来获取数据。但是当显示单个值时,explode()
会抱怨。
所以,我的问题是如何使某个属性的所有值成为spark数据帧中的数组?
答案 0 :(得分:1)
如果所有值都是标量,则可以使用array
函数:
import org.apache.spark.sql.functions._
array(col("A")).alias("A")
spark.read.json(
Seq("""{"A": "ae"}""").toDS).select(array(col("A")).alias("A")
).show
// +----+
// | A|
// +----+
// |[ae]|
// +----+
如果值混合,您可以手动解析事物:
import org.apache.spark.sql.types._
Seq("""{"A": "ae"}""", """{"A": ["ab", "cd"]}""").toDS.select(coalesce(
// Attempt to parse value as array<string>
from_json($"value", StructType.fromDDL("A array<string>"))("A"),
// If the first one fails, try to extract it as string and enclose with array
array(get_json_object($"value", "$.A"))
).alias("A")).show
// +--------+
// | A|
// +--------+
// | [ae]|
// |[ab, cd]|
// +--------+
如果您使用较旧的Spark版本替换:
StructType.fromDDL("A array<string>")
与
StructType(Seq(StructField("A", ArrayType(StringType))))