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

如何将多层字典列表转DataFrame及将DataFrame转时序DataFrame?解决报错

多层数据结构转DataFrame及时序数据转换解决方案

一、报错原因说明

触发TypeError: the JSON object must be str, bytes or bytearray, not Series的核心原因:

  • 误将存储Python字典的Series传入了json.loads()(该函数仅处理JSON字符串)
  • 使用pd.json_normalize()时直接传入Series,而非Series中每个元素的字典对象

二、需求1:多层字典列表转DataFrame

直接使用pd.json_normalize()即可自动展开多层嵌套结构,无需额外JSON解析。

代码示例

import pandas as pd

# 示例多层字典列表
multi_level_data = [
    {"device_id": "dev001", "metadata": {"channel": "CH01", "timezone": "UTC"}, "readings": [12.5, 13.2, 14.1]},
    {"device_id": "dev002", "metadata": {"channel": "CH02", "timezone": "GMT+8"}, "readings": [22.3, 23.5, 24.0]}
]

# 转换为结构化DataFrame
df = pd.json_normalize(multi_level_data)
print(df)

输出示例

device_idmetadata.channelmetadata.timezonereadings
dev001CH01UTC[12.5, 13.2, 14.1]
dev002CH02GMT+8[22.3, 23.5, 24.0]

三、需求2:含嵌套字典的DataFrame转时序DataFrame

针对包含Device_id、Attribute_xx列的原DataFrame,需将每个Attribute_xx列的嵌套字典展开,合并为统一的时序结构。

代码实现

import pandas as pd

# 模拟原DataFrame结构
original_df = pd.DataFrame({
    "Device_id": ["dev001", "dev002"],
    "Attribute_00": [
        {"channel": "CH01", "timezone": "UTC", "Readings": [10, 20, 30]},
        {"channel": "CH03", "timezone": "GMT+8", "Readings": [70, 80, 90]}
    ],
    "Attribute_01": [
        {"channel": "CH02", "timezone": "UTC", "Readings": [40, 50, 60]},
        {"channel": "CH04", "timezone": "GMT+8", "Readings": [100, 110, 120]}
    ]
})

# 提取所有Attribute列
attr_columns = [col for col in original_df.columns if col.startswith("Attribute_")]

# 批量处理每个Attribute列,生成临时DataFrame后合并
temp_dfs = []
for col in attr_columns:
    # 关联Device_id与当前列的嵌套字典
    temp = original_df[["Device_id", col]].copy()
    # 展开字典并与Device_id合并
    normalized = pd.json_normalize(temp[col])
    normalized["device_id"] = temp["Device_id"]
    # 保留目标列并重命名
    normalized = normalized[["device_id", "channel", "timezone", "Readings"]].rename(columns={"Readings": "readings"})
    temp_dfs.append(normalized)

# 合并所有临时DataFrame
timedf = pd.concat(temp_dfs, ignore_index=True)

# 可选:将readings列表展开为单条时序记录(根据需求选择)
timedf = timedf.explode("readings", ignore_index=True)

print(timedf)

输出示例(展开readings后)

device_idchanneltimezonereadings
dev001CH01UTC10
dev001CH01UTC20
dev001CH01UTC30
dev001CH02UTC40
dev002CH03GMT+870
dev002CH03GMT+880
dev002CH04GMT+8100

四、优化建议

  • 空值处理:处理前先通过original_df.dropna(subset=attr_columns)过滤含空字典的行,避免报错
  • 性能优化:针对超大规模数据,用列表存储临时DataFrame后一次性合并,减少内存开销
  • 结构校验:提前用original_df[attr_columns].applymap(lambda x: isinstance(x, dict))检查列内元素是否为字典,避免类型错误
  • 时序扩展:若readings是含时间戳的嵌套字典(如[{"timestamp": "2024-01-01", "value": 10}, ...]),可再次用pd.json_normalize()展开readings列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:00:31