Scala dev log

Spark(使用Scala) Row 转 JSON

将给定Dataframe的Row转为JSON格式

Q:需要将原数据帧A处理成以下数据帧B,其中C列包含原数据的C1,C2,C3列:
原数据帧A:

| 	 A  	|     B    	|  	C1 	 |  	C2  	|    C3   	|
-------------------------------------------------------------
| 	 1 		|	 test   | 	ab   |  	22	    | 	 TRUE   |
|  	 2 	    | 	mytest  | 	gh   | 	    17  	| 	 FALSE  |

处理后数据帧B:

| 	 A  	|     B    	|  				C 						  |
-------------------------------------------------------------------
| 	 1 		|	 test   | { "c1" : "ab", "c2" : 22, "c3" : TRUE } |
|  	 2 	    | 	mytest  | { "c1" : "gh", "c2" : 17, "c3" : FALSE }|

A:代码如下

// 1.添加json4s-native的依赖
import org.json4s._
import org.json4s.jackson.JsonMethods._

// 2.创建一个新的会话
val spark = SparkSession.builder().getOrCreate()

// 3.将数据帧A转为RDD, 再转为map
var dfAtoB= dfA.rdd.map(row => {
	val A = row.getAs[String]("A") //获取数据帧A中的A列
	val B = row.getAs[String]("B") //获取数据帧A中的B列
	val seq: Seq[String] = Seq( "C1","C2","C3") //过滤条件: 过滤一行中需要转为json的列
	Row(A, B, convertRowSpecifiedValueToJson(row,seq))
})

// 创建新表包含的列
val structType = StructType(Seq(
    StructField("A", DataTypes.StringType, false),
    StructField("B", DataTypes.StringType, false),
    StructField("C", DataTypes.StringType, false)
    ))
// 创建数据帧B
var dfB = spark.createDataFrame(dfAtoB,structType)

  /**
  * 行数据转Json格式
  * @param row 行数据
  * @param seq 过滤条件: 过滤一行中需要转为json的列
  * @return json 字符串
  */
  def convertRowSpecifiedValueToJson(row: Row, seq: Seq[String]): String = {
    var m: Map[String,Object] = row.getValuesMap(row.schema.fieldNames)
     m = m.filter(x => seq.contains(x._1)) //过滤掉seq中不存在的列,  将seq中存在的列放入map中
     m = m.map(v => {
     // 如果该列的值为null 则将键值映射为 map(key,value) => (列名,"")
	 if(v._2 == null) (v._1, "") else v //v._1:列名 v._2:列的值
	})
    compact(render((Extraction.decompose(m)(DefaultFormats)))) // map转row
  }

Note: 如果想将整行的数据都转为json,则可以不传入seq过滤列,代码如下

  def convertRowValueToJson(row: Row): String = {
    var m: Map[String,Object] = row.getValuesMap(row.schema.fieldNames)
     m = m.map(v => {
     // 如果该列的值为null 则将键值映射为 map(key,value) => (列名,"")
	 if(v._2 == null) (v._1, "") else v //v._1:列名 v._2:列的值
	})
    compact(render((Extraction.decompose(m)(DefaultFormats)))) // map转row
  }

将整行处理为json 再作为一列返回原数据帧的结果如下所示:

| 	 A  	|     B    	|  				C 												  |
-------------------------------------------------------------------------------------------
| 	 1 		|	 test   | { "A" : "1","B" : "test","c1" : "ab", "c2" : 22, "c3" : TRUE }	 |
|  	 2 	    | 	mytest  | { "A" : "2","B" : "mytest", "c1" : "gh", "c2" : 17, "c3" : FALSE }|
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值