You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python读取含多个字典的JSON并加载为DataFrame的方法

读取失败原因

两类文件都不符合标准JSON规范,常规json库、pandas.read_json接口无法直接识别:

  • 第一类文件每行是Python字典格式,使用单引号包裹键和字符串值,而标准JSON要求字符串必须用双引号包裹
  • 第二类文件是多个独立JSON数组直接首尾拼接,数组间无分隔符、无外层包裹结构,不符合标准JSON的结构要求

第一类文件(逐行字典格式)读取方案

使用ast.literal_eval逐行解析即可,该方法可以安全解析Python原生字面量(字典、列表等),不存在代码注入风险。
完整示例代码:

import ast
import pandas as pd

records = []
# 替换为你的实际文件路径
with open("dict_format_file.txt", "r", encoding="utf-8") as f:
    for line in f:
        line = line.strip()
        if not line:
            continue
        # 解析当前行的字典结构
        record = ast.literal_eval(line)
        records.append(record)

# 直接转成DataFrame,此时b、a列存储的是二维数组
df = pd.DataFrame(records)

如果需要把b(买盘)、a(卖盘)的二维数组拆分成明细行,可以追加以下处理代码:

# 分别展开买盘、卖盘列,添加交易类型标记
df_bid = df.explode("b")[["E", "s", "b"]].rename(columns={"b": "value_pair"})
df_bid["trade_type"] = "bid"
df_ask = df.explode("a")[["E", "s", "a"]].rename(columns={"a": "value_pair"})
df_ask["trade_type"] = "ask"

# 合并后拆分价格、成交量字段,做类型转换
df_detail = pd.concat([df_bid, df_ask]).reset_index(drop=True)
df_detail[["price", "volume"]] = pd.DataFrame(df_detail["value_pair"].tolist(), index=df_detail.index)
df_detail = df_detail.drop(columns=["value_pair"])
df_detail["price"] = df_detail["price"].astype(float)
df_detail["volume"] = df_detail["volume"].astype(float)
# 时间戳转datetime,原字段E是毫秒级时间戳
df_detail["trade_time"] = pd.to_datetime(df_detail["E"], unit="ms")

第二类文件(连续二维数组格式)读取方案

使用json.JSONDecoder的raw_decode方法循环解析即可,该方法可以从指定位置开始解析合法JSON片段,返回解析结果和结束位置,刚好适配连续拼接的JSON结构。
完整示例代码:

import json
import pandas as pd

decoder = json.JSONDecoder()
all_rows = []
with open("array_format_file.txt", "r", encoding="utf-8") as f:
    content = f.read().strip()
    pos = 0
    while pos < len(content):
        # 从当前位置解析一个二维数组
        current_array, pos = decoder.raw_decode(content, pos)
        # 跳过数组之间的空白字符
        while pos < len(content) and content[pos].isspace():
            pos += 1
        # 把当前数组的所有价格成交量对加入总列表
        all_rows.extend(current_array)

# 转成DataFrame,根据业务含义命名字段即可
df = pd.DataFrame(all_rows, columns=["price", "volume"])
# 转换数值类型
df["price"] = df["price"].astype(float)
df["volume"] = df["volume"].astype(float)

注意:禁止直接使用eval()解析文件内容,如果文件被恶意篡改,eval()会执行任意恶意代码,上述用到的ast.literal_eval和json.JSONDecoder.raw_decode均为安全解析方法,不存在该风险。

内容的提问来源于stack exchange,提问作者Thelvguy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:25:33