JSON第二弹

157 阅读2分钟

问题:将DataFrame中的一列字典重新转换为一个DataFrame,其中字典key是列名,value是列值。

image.png *思考: 每一行都是一个字典,且在dataframe中是字符串形式,若采用循环遍历的方式将每一行转换为dataframe然后再合并则耗时严重。考虑到字典以及字符串是最接近JSON文件的格式,能否采用一种JSON文件操作方法,快速转换结构形式?


1. JSON存储以及加载中的一些BUG

单引号字符串直接写入JSON是有问题的

obj2 = """
[{'*_6': "F000681Y0022",
 '$Num_10': '9',
 '$Num_11': '171'
 }]"""
with open("test.json","w",encoding="utf-8") as f:
    f.write(obj2)

image.png
字符串直接写入的正确写法

obj="""[{"姓名": "张三",
 "住处": "天朝",
 "宠物": "koala",
 "兄弟": "李四"
},{"姓名": "李四",
 "住处": "天朝",
 "宠物": "cat",
 "兄弟": "张三"}]"""
 with open("test.json","w",encoding="utf-8") as f:
    f.write(obj)

image.png
若为单引号,如何写入?使用json.dumps()将字典转换为字符串再写入

obj2 = [{'*_6': "F000681Y0022",
 '$Num_10': '9',
 '$Num_11': '171'
 }]
with open("test.json","w",encoding="utf-8") as f:
    y = json.dumps(obj2)
    f.write(y)

image.png

2. 解决今天问题

第一步:将dataframe中该列字符串式的字典转变为列表,1w行耗时0.01s。
第二步:将列表中的字符串式的字典用eval()方法还原为字典格式。1w行耗时0.01s。此时数据形式为一个大列表,列表中包含很多字典。
第三步:将该大列表使用json.dumps()方法转变为一个大的字符串,写入JSON文件中。
第四步:从JSON文件中读出整个内容,有两种方式,第一种为pd.read_json();第二种先读出来,然后使用json.loads()还原为原来的列表格式,再用pd.json_normalize()转变为dataframe格式。1w数据量耗时0.5s。

import json

variable = df['variables'].values.tolist()
var = [eval(var) for var in variable]
with open('test.json', mode='w', encoding='utf-8') as f:
    y = json.dumps(var)
    f.write(y)

# 方法一
data = open('test.json', encoding='utf-8').read()
data_list = json.loads(data)
da = pd.json_normalize(data_list)
da

# 方法二
import pandas as pd
df = pd.read_json("test.json",encoding="utf-8", orient='records')
df

image.png

image.png

3. 以上功能集成为函数,独立解决该部分问题
import json
import pandas as pd
import time

def colTodf(df, colName, jsonPath):
    # dataframe中一列字典转换为字符串,key是列名
    # colName:原dataframe中待转换的列名
    # jsonName:存储中间过程json文件路径
    start = time.time()
    variable = df[colName].values.tolist()
    var = [eval(var) for var in variable]
    with open(jsonPath, mode='w', encoding='utf-8') as f:
        y = json.dumps(var)
        f.write(y)
    data = pd.read_json(jsonPath, encoding='utf-8', orient='records')
    print(time.time() - start)
    return data

1w数据量耗时1.1s

能不能不存储到JSON中,直接转换为dataframe文件呢?

import json
import pandas as pd
import time

def colTodf(df, colName, jsonPath):
    # dataframe中一列字典转换为字符串,key是列名
    start = time.time()
    variable = df[colName].values.tolist()
    var = [eval(var) for var in variable]
    data = pd.json_normalize(var)
    data['stage'] = df['INDEX'].values
    print(time.time() - start)
    return data

这样耗时更短

完美解决!