Posts 使用Python, 将数据保存到json文件
Post
Cancel

使用Python, 将数据保存到json文件

一、 前言

前两天一直在搞人脸识别模块的完善工作, 在实现基本功能并排除可见的bug之后, 我开始试图对性能做一些优化

因为每次都需要对已知的人脸库重新编码, 会消耗一些时间: 现在的库很小, 所以重新编码也不是很困难, 如果是一个很大的库每次运行的代价就很大了, 大体思路就是把encodings保存到文件中, 在需要的时候可以读取, 这样就缩短了运行时间

二、 为什么是json?

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。

JSON建构于两种结构,

  • 一是“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。

  • 二是值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。

对于python, 我们可以顺利地将列表和字典写入json文件, 恰好这两种数据结构都是十分常用的

三、 如何使用python处理json?

在python中, 我们可以使用import json导入json模块, 使用相关的方法

3.1 dumps & dump

先写入一个json试试!

1
2
3
4
5
6
7
8
9
10
11
import json

#新建一个字典
dictionary = {'今天': ['7月22日','星期三'], '明天':['7月23日','星期四']}

# dumps()方法将数据保存为适用于json文件的字符串
dictionary_s = json.dumps(dictionary)

#将字符串写入文件
with open('hello.json','w',encoding='utf-8') as json_file:
    json_file.write(dictionary_s)

打开得到的json文件, 里面的内容如下:

1
{"\u4eca\u5929": ["7\u670822\u65e5", "\u661f\u671f\u4e09"], "\u660e\u5929": ["7\u670823\u65e5", "\u661f\u671f\u56db"]}

json文件中实际上就是以一种格式化的字符串的形式保存数据的, 如果感觉dumps()不够简洁, 这里有转化和写入二合一的dump()可以选择, 下面的代码和上面的代码是等价的:

1
2
3
4
5
6
7
8
import json

#新建一个字典
dictionary = {'今天': ['7月22日','星期三'], '明天':['7月23日','星期四']}

# dump()方法将数据保存为适用于json文件的字符串后存入文件
with open('hello.json', 'w', encoding='utf-8') as json_file:
    json.dump(dictionary, json_file)

3.2 indent & ensure_ascii

这两个都是dumps/dump的参数, 可以通过以下方式来指定

1
json.dump(dictionary, json_file, indent=2, ensure_ascii=False)
  • indent是指换行缩进, 制定后不仅会换行, 还会根据设定值缩进指定的空格数
  • ensure_ascii是指确保json文件的字符都可以用ascii码编码, 也就是上文那些转义的内容

仅指定indent=2时:

1
2
3
4
5
6
7
8
9
10
{
  "\u4eca\u5929": [
    "7\u670822\u65e5",
    "\u661f\u671f\u4e09"
  ],
  "\u660e\u5929": [
    "7\u670823\u65e5",
    "\u661f\u671f\u56db"
  ]
}

仅指定ensure_ascii=False时:

1
{"今天": ["7月22日", "星期三"], "明天": ["7月23日", "星期四"]}

3.3 loads & load

有dump自然就有load, 这一对和dumps/dump类似, 也是带s的直接与字符串相关, 不带s的直接与文件相关

我们读取上面创建的json文件:

1
2
3
4
5
6
7
8
import json

# 先读入json字符串, 再将json字符串转化成字典
with open('hello.json', 'r', encoding='utf-8') as json_file:
    dictionary_s = json_file.read()
    dictionary = json.loads(dictionary_s)

print(dictionary['今天'])

输出如下

1
['7月22日', '星期三']

也可以直接使用load, 与上面的代码等价

1
2
3
4
5
6
import json

with open('hello.json', 'r', encoding='utf-8') as json_file:
    dictionary = json.load(json_file)

print(dictionary['今天'])

四、 我遇到的问题

在做人脸识别的时候, 得到的编码信息是ndarray的格式, 当我试图将包含ndarray的字典写入json时, 得到了’无法序列化’的错误,我的解决方法是

  • 先用’.tolist()’将ndarray转换成list
  • 再用’numpy.array()’将list转回ndarray

所以在保存文件和打开文件的时候都需要一步转码

This post is licensed under CC BY 4.0 by the author.