这段时间学数据可视化,主要遇到的问题还是格式转换,这篇文章主要阐述一下我在python转json过程中遇到的问题和解决办法,如果有需要学习python可视化数据展示,可以看我其他两篇文章:
Flask+echarts+mysql实现数据大屏可视化
Flask+echarts+mysql+自动刷新
类型 | 函数 |
---|---|
py=>json | json.dumps() |
json=>py | json.loads() |
file=>py | json.loads() |
这里主要介绍py=>json:
假如你有一个数据集,可以是数组,可以是元组,也可以是列表,想把这些py类型的数据转为json,首先你要明白json是什么格式,例如
{"a":1,"b":2}
{"a":[1,2,3],"b":[4,5,6]}
{"a":"你好","b":"中国"}
{"a":["你好","中国"],"b":["我爱你","中国"]}
以上都是json格式,有没有发现这个和py的字典类型很像,都是键值对的形式展现数据,好了,如果你明白这个,接下来我们只需要我们py的数据类型改成字典格式,再利用转换函数就可以得到我们想要的json格式。
话不多说这里直接上代码体会,这里我以list举例,有一个列表(也可以是多个):
a = [1, 2, 3, 4, 5]
dict = {}
dict['a'] = a
print(dict)
print(type(dict))
b = json.dumps(dict)
print(b)
print(type(b))
# 这是结果 :
# {'a': [1, 2, 3, 4, 5]}
#
# {"a": [1, 2, 3, 4, 5]}
#
有没有发现虽然两个打印结果相同,但是类型却不同,好了,这里是介绍一下py的dict格式和json格式的差别.
从数据库中读取各种类型的数据,需要转化成json格式:
def mainData():
db = pymysql.connect(host='localhost', user='root', passwd='root', db='db_sea', port=3306, charset='utf8')
cur = db.cursor() # 游标(指针)cursor的方式操作数据
sql = f"select * from (select * from fisherybase where ad='桃花' order by id desc limit 30) aa ORDER BY id" # sql语句
cur.execute(sql) # execute(query, args):执行单条sql语句
catch_data = cur.fetchall()
# ((20, '桃花', '监测点1', datetime.datetime(2022, 4, 30, 15, 1, 54), Decimal('17.4'),
# 可以看到从数据库读出的数据,有字符串格式:'桃花','监测点1',datetime格式,decimal格式.
cur.close()
db.close()
# 先用列表把数据存下来
p = []
lt = []
wt = []
sal = []
do = []
ph = []
fv = []
ii = []
for i in catch_data:
p.append(i[2])
lt.append(i[3])
wt.append(i[4])
sal.append(i[5])
do.append(i[6])
ph.append(i[7])
fv.append(i[8])
ii.append(i[9])
# 创建一个字典,键自己定义,值为列表
dict = {}
dict['p'] = p
dict['lt'] = lt
dict['wt'] = wt
dict['sal'] = sal
dict['do'] = do
dict['ph'] = ph
dict['fv'] = fv
dict['ii'] = ii
print(dict) # {'p': ['监测点1', '监测点2', '监测点3' ..... 这里就变成了字典格式了.
# 转为json格式
lastData = json.dumps(dict) # 待会这个方法会进行修改,请看解决办法
# type(lastData)
return lastData
# 结果都是报错,Object of type 'datetime' is not JSON serializable
# 或者 Object of type 'decimal' is not JSON serializable
# 或者字符串变成 "u/ddd" 类型的编码
class Decimal_and_DateEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime.datetime):
# 1.这里是解决日期datetime格式
return o.strftime("%Y-%m-%d %H:%M:%S")
# 2.这里是解决小数decimal格式
elif isinstance(o, decimal.Decimal):
return float(o)
else:
return json.JSONEncoder.default(self, o)
# 请把上述的json.dumps方法换成这里的dict_to_json即可
def dict_to_json(dict_data):
# 3.ensure_ascii=False 是解决字符串编码问题
axis_value = json.dumps(dict_data, cls=Decimal_and_DateEncoder, ensure_ascii=False)
return axis_value
代码可以直接用,这就是解决datetime,decimal,字符串乱码的方法,按照这个思路,也可以解决其他数据转化问题,欢迎留言区补充,如果对大家有帮助的话,点个赞吧~