深入解析JSON:从数据类型处理到地理数据可视化
立即解锁
发布时间: 2025-09-07 01:59:19 阅读量: 16 订阅数: 50 AIGC 


数据清洗的艺术与实践
### 深入解析JSON:从数据类型处理到地理数据可视化
#### 1. R语言中的JSON数据表示
在R语言里,并没有像字典或哈希表那样的标准数据结构。通常,JSON数据会用命名列表(一般是嵌套列表)来表示。下面的代码展示了如何读取JSON文件并查看列表的第三个元素:
```R
library(rjson)
result <- fromJSON(file = "data/3001.json")
result[3]
```
输出结果如下:
```
$'3'
$'3'$name
[1] "Ken Thompson"
$'3'$password
[1] "p/q2-q4!"
$'3'$details
$'3'$details$profession
[1] "Unix Creator"
```
其他编程语言的写法可能不同,但都可以借助库或标准函数在原生数据和JSON之间进行转换。
#### 2. JSON的NaN处理与数据类型
JSON语法的半正式描述隐藏着一些潜在问题。在JSON里,只有“number”这一语法类型,并没有对整数、浮点数、小数、复数、分数/有理数以及数字的位长进行区分。如何解释数值完全取决于库或者用户自己。
此外,JSON无法表示IEEE - 754浮点数中的特殊值,如Not - a - Number (NaN)和Infinity / - Infinity。虽然很多编程语言都有表示这些值的方式,但JSON标准不支持。
在Python中,标准库和常见的JSON解析器会做一个启发式假设:包含小数点或指数的数字表示浮点数,没有的则表示整数。不过,这种假设存在一些边缘情况。例如,像1e309这样的数字,本可以精确地用Python的无限大小整数表示,但却被当作浮点数处理,从而导致精度丢失。
下面是一个简单的例子,展示了Python和R在处理JSON数值时的溢出和截断问题:
```python
import json
# An interpreted float, an overflow, and a truncation
json_str = "[1e308, 1e309, 1.2345678901234567890]"
json.loads(json_str)
```
输出:
```
[1e+308, inf, 1.2345678901234567]
```
在R中:
```R
# R代码
options(digits = 22)
fromJSON(json_str)
```
输出:
```
[1] 1.000000000000000010979e+308 Inf
[3] 1.234567890123456690432e+00
```
Python的`decimal`模块提供了更接近JSON数字语法的替代方案。第三方模块`simplejson`能方便地处理这种情况:
```python
import simplejson
simplejson.loads(json_str, use_decimal=True)
```
输出:
```
[Decimal('1E+308'), Decimal('1E+309'), Decimal('1.2345678901234567890')]
```
而JavaScript和R等语言缺乏标准的十进制或无限精度数据类型,在表示某些语法有效的JSON数字时会丢失精度。
#### 3. 特殊值处理
Python的默认“JSON”库实际上读取和写入的是JSON的超集,可能包含NaN、Infinity和 - Infinity等额外字面量。JSON5提案包含了这些扩展,但目前还不是官方标准。
下面是Python处理特殊值的例子:
```python
import json
specials = "[NaN, Infinity, -Infinity]"
vals = json.loads(specials)
vals
```
输出:
```
[nan, inf, -inf]
```
R语言的`rjson`库对特殊值的处理方式与Python不同。R会把特殊值表示为带有特殊提示值的字符串:
```R
vals = c(NaN, Inf, -Inf)
print(vals)
print("R version of 'enhanced JSON':")
rjson_str = toJSON(vals) # function from rjson library
print(rjson_str)
```
输出:
```
[1] NaN Inf -Inf
[1] "R version of 'enhanced JSON':"
[1] "[\"NaN\",\"Inf\",\"-Inf\"]"
```
不过,这种方法在数据往返时会失败,除非编写自定义代码来解释字符串。
#### 4. JSON Lines
JSON常用于编码小数据束,比如日志文件。JSON流式处理是减轻解析负担的有效方法。Newline Delimited JSON (ndjson) 或JSON Lines是聚合小JSON文档的常用方式。除了换行符分隔,还有其他几种方式:
- **记录分隔符分隔**:使用Unicode字符INFORMATION SEPARATOR TWO (U + 001E) 作为分隔符(RFC 7464),JSON文档中可以包含换行符。
- **连接JSON**:不使用分隔符,每个JSON条目是一个对象或数组,流式解析器可以通过匹配`}`或`]`来识别顶级结构的结束。
- **长度前缀JSON**:每个条目由一个整数表示剩余条目的字节数,后面跟着一个JSON对象或数组。
下面是一个JSON Lines的例子:
```bash
cat -n data/jsonlines.log | fmt -w55 | tr -d " "
```
输出:
```
1 {"ts":"2020-06-18T10:44:13",
"logged_in":{"username":"foo"},
"connection":{"addr":"1.2.3.4","port":5678}}
2 {"ts":"2020-06-18T10:44:15",
"registered":{"username":"bar","email":"[email protected]"},
"co
```
0
0
复制全文
相关推荐









