我有一些像下面这样的json数据,我需要根据一些Jason值创建新列
{“开始”:“ 1234567679”,“测试”:[“ abc”],“值”:324,“结束”:“ 1234567689”}
{“开始”:“ 1234567679”,“测试”:[“ xyz”],“值”:“附近”,“结束”:“ 1234567689”}
{“开始”:“ 1234568679”,“测试”:[“ pqr”],“值”:[“ Attr”,“”],“结束”:“ 1234568679”}}
{“开始”:“ 1234568997”,“测试”:[“ mno”],“值”:[“ {\”键\“:\” 1 \“,\”值\“:[\” 789 \“]}”],“ end”:“ 1234568999”}
上面是json示例
我想创建一个如下所示的列
start abc xyz pqr mno end
1234567679 324 null null null 1234567689
1234567889 null Near null null 1234567989
1234568679 null null attr null 1234568679
1234568997 null null null 789 1234568999
def getValue1(s1: Seq[String], v: String) = {
if (s1(0)=="abc")) v else null
}
def getValue2(s1: Seq[String], v: String) = {
if (s1(0)=="xyz")) v else null
}
val df = spark.read.json("path to json")
val tdf = df.withColumn("abc",getValue1($"test", $"value")).withColumn("xyz",getValue2($"test", $"value"))
但这是我不想使用的,因为我的测试值更多,我希望某些函数执行类似的操作
def getColumnname(s1: Seq[String]) = {
return s1(0)
}
val tdf = df.withColumn(getColumnname($"test"),$"value"))
将值更改为列是否是个好主意,我想这样,因为我需要将其应用于需要普通列的某些机器学习代码中
答案 0 :(得分:0)
您可以使用数据透视操作来执行此类操作。假设您在test
列的数组中始终只有一项,这是更简单的解决方案;
import org.apache.spark.sql.functions._
val df = sqlContext.read.json("<yourPath>")
df.withColumn("test", $"test".getItem(0)).groupBy($"start", $"end").pivot("test").agg(first("value")).show
+----------+----------+----+----+
| start| end| abc| xyz|
+----------+----------+----+----+
|1234567679|1234567689| 324|null|
|1234567889|1234567689|null| 789|
+----------+----------+----+----+
如果test
列中有多个值,则还可以使用explode
函数;
df.withColumn("test", explode($"test")).groupBy($"start", $"end").pivot("test").agg(first("value")).show
有关更多信息:
希望对您有帮助!
根据您的评论和更新的问题,这是您需要遵循的解决方案。我已经 有意 分隔了所有操作,因此您可以轻松了解需要做哪些进一步的改进;
df.withColumn("value", regexp_replace($"value", "\\[", "")). //1
withColumn("value", regexp_replace($"value", "\\]", "")). //2
withColumn("value", split($"value", "\\,")). //3
withColumn("test", explode($"test")). //4
withColumn("value", explode($"value")). //5
withColumn("value", regexp_replace($"value", " +", "")). //6
filter($"value" !== ""). //7
groupBy($"start", $"end").pivot("test"). //8
agg(first("value")).show //9
当您读取此类json文件时,它将为您提供一个数据框,其中的value
列带有StringType
。您无法直接将StringType
转换为ArrayType
,因此您需要执行第1、2、3行中的技巧,将其转换为ArrayType
。 您可以一行执行这些操作,也可以仅使用一个正则表达式或定义udf。一切取决于您,,我只是想向您展示Apache Spark的功能。
现在您在value
列中有ArrayType
。就像在第4行的test
列中所做的那样,在第5行中展开该列。然后应用您的数据透视操作。