前言
 
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数据。
 
 
 
 
 

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

  1. python中json格式数据输出实现方式

    python中json格式数据输出实现方式 主要使用json模块,直接导入import json即可. 小例子如下: #coding=UTF-8 import json info={} info[&q ...

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

    前文中我们把网络爬虫爬取的数据保存为JSON格式,但为了能够更方便地处理数据.我们希望把这些数据导入到MySQL数据库中.phpMyadmin能够把MySQL数据库中的数据导出为JSON格式文件,但却 ...

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

    本文将从四个方面对IOS开发中JSON格式数据的生成与解析进行讲解: 一.JSON是什么? 二.我们为什么要用JSON格式的数据? 三.如何生成JSON格式的数据? 四.如何解析JSON格式的数据? ...

  4. fastJson java后台转换json格式数据

    什么事JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Progra ...

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

    Json 和 Jsonlib 的使用 什么是 Json JSON(JvaScript Object Notation)(官网网站:http://www.json.org/)是 一种轻量级的数据交换格式 ...

  6. 转载 -- iOS开发之JSON格式数据的生成与解析

    本文将从四个方面对IOS开发中JSON格式数据的生成与解析进行讲解: 一.JSON是什么? 二.我们为什么要用JSON格式的数据? 三.如何生成JSON格式的数据? 四.如何解析JSON格式的数据? ...

  7. Django 1.8.11 查询数据库返回JSON格式数据

    Django 1.8.11 查询数据库返回JSON格式数据 和前端交互全部使用JSON,如何将数据库查询结果转换成JSON格式 环境 Win10 Python2.7 Django 1.8.11 返回多 ...

  8. 解析json格式数据

    实现目标 读取文件中的json格式数据,一行为一条json格式数据.进行解析封装成实体类. 通过google的Gson对象解析json格式数据 我现在解析的json格式数据为: {",&qu ...

  9. ios网络学习------6 json格式数据的请求处理

    ios网络学习------6 json格式数据的请求处理 分类: IOS2014-06-30 20:33 471人阅读 评论(3) 收藏 举报 #import "MainViewContro ...

随机推荐

  1. Qt 学习之路 :Qt 绘制系统简介

    Qt 的绘图系统允许使用相同的 API 在屏幕和其它打印设备上进行绘制.整个绘图系统基于QPainter,QPainterDevice和QPaintEngine三个类. QPainter用来执行绘制的 ...

  2. [转] JAVA的Random类

    Random类 (java.util) Random类中实现的随机算法是伪随机,也就是有规则的随机.在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要 ...

  3. 对于android拦截短信的一些疑问

    最近折腾android4.4短信拦截的问题,要求在app上收到短信的时候弹出提示,并显示的功能. 然后找到了使用broadcastreceiver和contentprovider两种方法,那么问题来了 ...

  4. android requestWindowFeature使用详解

    requestWindowFeature可以设置的值有:          1.DEFAULT_FEATURES:系统默认状态,一般不需要指定          2.FEATURE_CONTEXT_M ...

  5. 网站项目:让一般处理文件.ashx的代码有折叠功能(#region)

    注意:该方法用于网站项目.但对于其他类型的项目有一定的参考作用. 1.首先在你想被别人访问的位置新建一个ashx文件,如/System/xxx.ashx. 新建xxx.ashx的代码如下: [csha ...

  6. Webview的使用和注意事项

    1.webView是一个展示web网页的控件,继承 AbsoluteLayout 2.webview的俩个回调应用层: 1)webViewClient 这个对象的创建 WebViewClient my ...

  7. JavaScript--函数-按值传递

    按值传递(byValue): 两个变量间赋值或将变量作为参数传入函数时,其实都是将原变量中的值,赋值一份给对方(新变量) 对原始类型的值: 修改新变量,不会影响原变量 对引用类型的对象: 通过新变量修 ...

  8. 实现textarea限制输入字数

    实现textarea限制输入字数(包含中文只能输入10个,全ASCII码能够输入20个) textarea称文本域,又称文本区,即有滚动条的多行文本输入控件,在网页的提交表单中经常用到.与单行文本框t ...

  9. C++ 异常处理执行过程

    看<clean code>时,又遇到异常处理的例程. 看不明白是因为我一直都将异常处理束之高阁. 今天晚上下决心去找资料看看,看完之后觉得以前是把它想得太难,其实非常简单. 希望以后遇到问 ...

  10. 嵌入式开发(一) Ubuntu12.04下搭建交叉编译环境

    操作系统:Ubuntu12.04 AMD64位 交叉编译环境:arm-Linux gcc版本4.4.3 前言: 首先理解一下交叉编译的意思.我们要给嵌入式设备写应用程序,但是又不能在嵌入式设备上完成所 ...