1. 将字典序列化为json文件
def save_to_json(dict, out_path):
dict_json = json.dumps(dict)
f = open(out_path, 'w')
f.write(dict_json)
f.close()
2. 加载json文件
def get_json_data(json_path):
with open(json_path) as f:
data = json.load(f)
return data
3. 序列化问题—TypeError:array is not json serializable
将字典序列化为json文件过程中,可能遇到上述问题,原因是字典中某些value为np.array
- 正确示例(未使用array作为value)
a = [1,2,3]
# b = np.array(a)
dict = {"1": "string","2": 1024,"3": a,
# "4": b
}
dict_json = json.dumps(dict)
f = open("../dyh_res/tmp.json", 'w')
f.write(dict_json)
f.close()
- 错误示例(使用array作为value)
a = [1,2,3]
b = np.array(a)
dict = {"1": "string","2": 1024,"3": a,
"4": b
}
dict_json = json.dumps(dict)
f = open("../dyh_res/tmp.json", 'w')
f.write(dict_json)
f.close()
4. 解决方案:.tolist()
(1)简易版
即在序列化前将array转为list,加载时候再转回array
dict = {"1": "string","2": 1024,"3": a,
"4": b.tolist()
}
with open("../dyh_res/tmp.json") as f:
data = json.load(f)
print(data)
data['4'] = np.array(data['4'])
print(data)
(2)加强版
上述方法需要对字典中每个array都手动tolist,不如干脆写一个class来解决~
# 编码类
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.ndarray):
return obj.tolist()
return json.JSONEncoder.default(self, obj)
a = [1,2,3]
b = np.array(a)
dict = {"1": b,"2": b,"3": b,"4": b}
dict_json = json.dumps(dict, cls=NumpyEncoder) # 调用编码类
# 保存数据
f = open("../dyh_res/tmp.json", 'w')
f.write(dict_json)
f.close()
# 加载数据
with open("../dyh_res/tmp.json") as f:
data = json.load(f)
print(data)
for key,value in data.items(): # 按照具体需要,恢复ndarray
if isinstance(value, list):
data[key] = np.array(value)
print(data)
(3)附:该编码类的详尽版本
class NumpyEncoder(json.JSONEncoder):
""" Special json encoder for numpy types """
def default(self, obj):
if isinstance(obj, (np.int_, np.intc, np.intp, np.int8,
np.int16, np.int32, np.int64, np.uint8,
np.uint16, np.uint32, np.uint64)):
return int(obj)
elif isinstance(obj, (np.float_, np.float16, np.float32,
np.float64)):
return float(obj)
elif isinstance(obj,(np.ndarray,)): #### This is the fix
return obj.tolist()
return json.JSONEncoder.default(self, obj)
参考: stackoverflow