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

如何用Python读取大型JSON数据集,无需指定所有子节点名称

如何无需指定键名读取大型JSON数据集(Python)?

我明白你的需求——不想硬编码一堆JSON的键名来读取数据,尤其是面对大型数据集的时候,硬编码不仅麻烦还容易出错。先看看你提供的这段样本JSON:

{
  "series": [
    {"name": "G", "type": "c8y_g_ist", "unit": ""},
    {"name": "T", "type": "c8y_t_rohr_ist", "unit": "C"},
    {"name": "P", "type": "c8y_ph_soll_ist", "unit": "ph"},
    {"name": "T", "type": "c8y_t_tank_ist", "unit": "C"},
    {"name": "V", "type": "c8y_v_rohr_ist", "unit": "m/s"},
    {"name": "Bio", "type": "c8y_NO3_Wert", "unit": "mg/l"},
    {"name": "T", "type": "c8y_t_rohrsurface_ist", "unit": "C"},
    {"name": "Bio", "type": "c8y_PO4_Wert", "unit": "mg/l"},
    {"name": "P", "type": "c8y_ph_ist", "unit": "ph"},
    {"name": "Bio", "type": "OD_Wert", "unit": ""}
  ],
  "truncated": false,
  "values": {
    "2018-03-15T00:00:17.000Z": [{"max": 92.78, "min": 92.78}, {"max": 3.21, "min": 3.21}],
    "2018-03-15T00:05:18.000Z": [null, {"max": 3.2, "min": 3.2}],
    "2018-03-15T00:06:49.000Z": [{"max": 92.78, "min": 92.78}, {"max": 3.2, "min": 3.2}, {"max": 5, "min": 5}, {"max": 3.64, "min": 3.64}, {"max": 0, "min": 0}, {"max": 0, "min": 0}, {"max": 3.04, "min": 3.04}, {"max": 0, "min": 0}, {"max": 0, "min": 0}, {"max": 0, "min": 0}],
    "2018-03-15T00:10:17.000Z": [{"max": 95.22, "min": 95.22}, {"max": 3.14, "min": 3.14}, null, {"max": 3.57, "min": 3.57}, {"max": 0.01, "min": 0.01}, null, {"max": 2.97, "min": 2.97}, null, null, null],
    "2018-03-15T00:15:17.000Z": [{"max": 92.78, "min": 92.78}, {"max": 3.13, "min": 3.13}, null, null, {"max": 0, "min": 0}, null, null, null, null, null]
  }
}

下面给你几个实用的Python方案,完全不需要指定所有子部分的名称:

方法1:递归提取所有非结构化数值

如果你的需求只是把所有有效数值(排除null)都提取出来,不管它在JSON里的位置,可以写一个递归遍历函数,自动遍历字典和列表的所有层级:

def extract_all_values(data):
    # 如果是字典,遍历所有值
    if isinstance(data, dict):
        for value in data.values():
            yield from extract_all_values(value)
    # 如果是列表,遍历所有元素
    elif isinstance(data, list):
        for item in data:
            yield from extract_all_values(item)
    else:
        # 只返回非None的数值
        if data is not None:
            yield data

# 使用示例
# 假设你的JSON数据已经解析成Python字典,存在response变量中
response = {...}  # 这里替换成你的实际数据

# 提取所有有效数值
all_values = list(extract_all_values(response))
print(all_values)

这个函数会自动钻进JSON的每一层,把所有不是容器(字典/列表)的非None值都捞出来,完全不用管键名是什么。

方法2:动态关联元信息与指标数据

从你的JSON结构来看,series里的每个元素和values中每个时间戳对应的数组元素是一一对应的(比如第一个series对应每个时间点数组的第一个元素)。我们可以利用这个对应关系,动态关联指标的元信息(名称、类型、单位)和数值,不用硬编码任何键名:

# 先获取series的元信息列表
series_metadata = response['series']

# 遍历每个时间点的指标数据
for timestamp, metric_list in response['values'].items():
    print(f"=== 时间点: {timestamp} ===")
    # 用索引关联元信息和对应的数值
    for idx, metric_data in enumerate(metric_list):
        if metric_data is not None:
            # 动态获取当前指标的元信息
            meta = series_metadata[idx]
            print(f"指标: {meta['name']} ({meta['type']})")
            print(f"单位: {meta['unit']}")
            print(f"最大值: {metric_data['max']}, 最小值: {metric_data['min']}\n")

这个方案的好处是,就算后续series新增了指标,代码完全不用修改,会自动适配新的结构,非常适合维护大型数据集。

方法3:流式处理超大型JSON(避免内存溢出)

如果你的JSON数据集大到没法一次性加载到内存(比如几GB大小),可以用ijson库来流式读取,它会把JSON拆成一个个小的事件,逐段处理,不会占用太多内存:

首先需要安装ijson:

pip install ijson

然后用下面的代码流式处理:

import ijson

# 假设从文件读取超大型JSON
with open('large_cloud_data.json', 'r', encoding='utf-8') as f:
    # 解析JSON,遍历所有事件
    for prefix, event, value in ijson.parse(f):
        # 只处理max和min数值(可以根据prefix过滤你需要的内容)
        if prefix.endswith('.max') or prefix.endswith('.min'):
            print(f"数据路径: {prefix}, 数值: {value}")

比如prefix会返回类似values.2018-03-15T00:00:17.000Z.0.max这样的路径,你可以根据这个路径来筛选需要的数据,完全不用提前知道所有键名。

进阶:转成DataFrame方便数据分析

如果要做进一步的数据分析,把数据转成Pandas DataFrame会非常方便,同样可以动态生成列名,不用硬编码:

import pandas as pd

series_metadata = response['series']
rows = []

# 遍历每个时间点,整理成一行数据
for timestamp, metric_list in response['values'].items():
    row = {'timestamp': timestamp}
    for idx, metric_data in enumerate(metric_list):
        meta = series_metadata[idx]
        # 动态生成列名,比如G_max、G_min
        if metric_data is not None:
            row[f"{meta['name']}_max"] = metric_data['max']
            row[f"{meta['name']}_min"] = metric_data['min']
        else:
            row[f"{meta['name']}_max"] = None
            row[f"{meta['name']}_min"] = None
    rows.append(row)

# 转成DataFrame
df = pd.DataFrame(rows)
# 查看前5行
print(df.head())

这样生成的DataFrame会自动把每个指标的最大值和最小值作为列,时间戳作为索引,后续做统计、可视化都非常方便。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:03:41