Spark处理Json格式数据(Python)

前言

Spark能够自动推断出Json数据集的“数据模式”(Schema),并将它加载为一个SchemaRDD实例。这种“自动”的行为是通过下述两种方法实现的:

jsonFile:从一个文件目录中加载数据,这个目录中的文件的每一行均为一个JSON字符串(如果JSON字符串“跨行”,则可能导致解析错误);

jsonRDD:从一个已经存在的RDD中加载数据,这个RDD中的每一个元素均为一个JSON字符串;

这里我们仅讨论jsonFile的场景,jsonRDD处理方法类似。

典型示例

JSON的数据模式是非常灵活的,我们例举常见的几种可能性进行讨论。

(1)JSON文件中的数据模式一致,每一行的数据均为JSON字符串(非JSON数组)

假设数据模式包含三个属性:id、name、birthdate,测试数据如下所示:

Python测试代码如下:

在终端上执行可以看到有两部分输出:

可以看到数据模式一致的情况下,数据模式被正确推断,数据被正确解析。

(2)JSON文件中的数据模式一致,每一行的数据均为JSON数组字符串

假设数据模式包含三个属性:id、name、birthdate,测试数据如下所示:

Python测试代码同上,在终端上执行可以看到有两部分输出:

可以看到数据数据模式被正确推断,JSON数组中的“多个”对象数据被正确解析,解析结果共有三行。

(3)JSON文件中的数据模式一致,但每一行数据以两种形式出现:JSON字符串(非数组)、JSON数组字符串

假设数据模式包含三个属性:id、name、birthdate,测试数据如下所示:

其中第一行为JSON数组字符串,包含有两个JSON对象;第二行为JSON字符串,表示一个JSON对象。

Python测试代码同上,在终端上执行可以看到有两部分输出:

可以看到数据行混搭的情况下(同时包含JSON字符串(非数组)和JSON数组字符串),数据数据模式被正确推断,数据被正确解析。

(4)JSON文件中的数据模式不一致

假设数据模式有以下两种情况:

模式一:id、name、birthdate

模式二:id、name、birthdate、weight

测试数据如下所示:

其中第一行数据为JSON数组字符串,数据模式为模式一;第二行数据为JSON字符串(非数组),数据模式为模式二。

Python测试代码同上,在终端上执行可以看到有两部分输出:

可以看到数据模式被推断为模式二,数据也是按照模式二被解析;模式二相对于模式一多出一个属性“weight”,如果数据匹配模式一,则属性“weigth”的值以“None”的形式出现。

数据模式不一致还有一种比较复杂的情况:模式交错,如下:

模式一:id、name、birthdate、height

模式二:id、name、birthdate、weight

测试数据如下所示:

Python测试代码同上,在终端上执行可以看到有两部分输出:

可以看出数据模式被推断为模式一与模式二的并集,缺失的属性以“None”的形式出现。

结论:数据模式不一致时,推断模式为多个数据模式的并集。

(5)JSON文件中的数据模式不一致,且数据模式存在类型多样以及嵌套的情况;

模式一:id、name、birthdate、msg、extras

模式二:id、name、birthdate、weight

测试数据如下所示:

第一行是一个JSON数组字符串,包含两个JSON字符串,每个JSON字符串的属性msg是一个JSON字符串,属性extras是一个JSON数组字符串。

Python测试代码同上,在终端上执行可以看到有两部分输出:

可以看出数据模式被推断为模式一与模式二的并集,其中msg被解析为struct类型,extras被解析为array类型(元素类型为struct),缺失的属性以“None”的形式出现。

如果我们需要处理的JSON数据的模式是不一致的(对象属性不一致),我们在代码逻辑中如何进行判断呢?以(5)中的测试数据为例,属性weight并不是出现在所有数据行中,为了避免运行时抛出异常,需要根据是否包含属性weight作出不同的处理,这时就需要用到Python内建函数hasattr,如下:

代码中函数handle的作用:如果对象row含有属性weight,则返回对应的属性值;否则返回“no value”。而判断row是否含有属性“weight”是使用函数hasattr实现的。

通过上述的几个示例我们可以发现Spark可以正确应对常见的JSON日志格式,但我们在充分利用JSON特性的同时(日志属性灵活扩展、JSON处理方式统一),也应该考虑合理设计JSON日志数据模式,避免数据模式不一致或数据模式复杂给数据分析带来的不便。

jsonFile相当于是Spark提供给我们的便利工具,省去了我们自己解析JSON数据的麻烦,但也可能会出现工具失效的情况,大部分原因来自于数据格式不统一或不规范,此时我们就得自己解析JSON数据。

Python自带了一个操作JSON数据的库“json”,我们会经常使用到两个方法:

dumps:用于JSON对象序列化,即JSON对象 —> JSON字符串

loads:用于JSON字符串反序列化,即JSON字符串 —> JSON对象

方法使用示例如下所示:

解决了JSON数据的序列化与反序列化的问题后,还需要考虑一个情况:

数据分析时多数需要处理的都是文本数据,我们将一行文本(字符串)反序列化为一个JSON对象后,我们如何判断这个对象是一个普通JSON对象,还是一个JSON数组?特别是我们需要根据不同的数据类型进行不同的处理时,这种数据类型的判断就不可避免。

此时我们就需要用到Python的内建函数:isinstance,如下所示:

在终端执行上述代码,可得结果:

可以看出JSON数组对象的类型为“list”,而普通JSON对象的类型为“dict”。

总结

Spark在处理JSON数据时通常可以直接使用jsonFile,如果数据格式不统一、不规范或者我们需要更为灵活的数据处理方式时,则可以将文本数据以字符串的形式按行读入,然后使用Python JSON相关库、内建函数自行解析JSON数据。

时间: 2024-11-05 06:25:43

Spark处理Json格式数据(Python)的相关文章

Python将JSON格式数据转换为SQL语句以便导入MySQL数据库

前文中我们把网络爬虫爬取的数据保存为JSON格式,但为了能够更方便地处理数据,我们希望把这些数据导入到MySQL数据库中.phpMyadmin可以把MySQL数据库中的数据导出为JSON格式文件,但却不能把JSON格式文件导入到MySQL数据库.为了实现这个目标,可以编写Python脚本将JSON格式数据转换为SQL语句以便导入MySQL数据库. JSON文件tencent.json部分内容: {"recruitNumber": "1", "name&qu

fastJson java后台转换json格式数据

什么事JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等

java后台对json格式数据的解析

Json 和 Jsonlib 的使用 什么是 Json JSON(JvaScript Object Notation)(官网网站:http://www.json.org/)是 一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成.它基于 JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999 的一个子集. JSON 采用完全独立于语言的文本格式,但是也使用了类似于 C 语言家族

iOS开发之JSON格式数据的生成与解析

本文将从四个方面对IOS开发中JSON格式数据的生成与解析进行讲解: 一.JSON是什么? 二.我们为什么要用JSON格式的数据? 三.如何生成JSON格式的数据? 四.如何解析JSON格式的数据?  JSON格式取代了xml给网络传输带来了很大的便利,但是却没有了xml的一目了然,尤其是json数据很长的时候,我们会陷入繁琐复杂的数据节点查找中.这时我们就需要一款在线校验工具 BeJson. 一.JSON是什么? JSON(JavaScript Object Notation) 是一种轻量级的

java将XML文档转换成json格式数据

功能 将xml文档转换成json格式数据 说明 依赖包: 1. jdom-2.0.2.jar : xml解析工具包; 2. fastjson-1.1.36.jar : 阿里巴巴研发的高性能json工具包 程序源码 package com.xxx.open.pay.util; import com.alibaba.fastjson.JSONObject; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdo

Android上解析Json格式数据

package com.practice.json; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class JsonDemo extends Activity { /*http://www.hui

使用getJSON()异步请求服务器返回json格式数据

我们可以使用jquery的getJSON()方法请求服务器返回json格式数据: js代码: function test(){ $.getJSON("JsonServlet",function(result){ alert(result.name); }); } 服务器端servlet响应: @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletEx

解析JSON格式数据

 别想一下造出大海,必须先由小河川开始. 本讲内容:解析JSON格式数据 1)比起XML,JSON的主要优势在于它的体积更小,在网络上传输的时候可以更省流量.但缺点在于,它的语义性较差,看起来不如XML直观. 2)解析JSON格式的数据有多种方式,常用的两种是:使用官方提供的JSONObject和谷歌的开源库GSON. 示例一:解析服务器返回的数据 一.JSONObject解析方式 步骤: 1.在服务器中定义一个JSONArray,并将服务器返回的数据传入到JSONArray对象中 2.循环

springmvc4.0配置ajax请求json格式数据

1.导入相关jar包:jackson-annotation-2.5.4.jar,jackson-core-2.5.4.jar,jackson-databind-2.5.4.jar. 2.spring-servlet.xml中相关配置: //命名空间加入mvc: xmlns:mvc="http://www.springframework.org/schema/mvc" //xsi:schemaLocation中补充: http://www.springframework.org/sche