如何在Python中对JSON数据同ID的POK与TOK值做减法?
按ID计算POK与TOK差值的Python实现方案
我来帮你搞定这个问题!核心问题是你之前提取POK、TOK列表时,没有把同一个id对应的两个值关联起来。所以第一步要按id分组,把每个id对应的POK和TOK值绑定在一起,之后就能轻松完成减法运算了。下面是具体的解决方案和优化思路:
基础实现代码
这是完整的可运行代码,包含JSON解析、分组和差值计算的全流程:
import json # 你的原始JSON数据 raw_json = '''{ "data": [ { "id": "1", "type": "POK", "value": "34" }, { "id": "1", "type": "TOK", "value": "32" }, { "id": "1", "type": "POC", "value": "43" }, { "id": "2", "type": "POK", "value": "45" }, { "id": "2", "type": "TOK", "value": "67" }, { "id": "3", "type": "POK", "value": "12" }, { "id": "2", "type": "POC", "value": "23" }, { "id": "3", "type": "TOK", "value": "34" } ] }''' # 解析JSON数据 data_list = json.loads(raw_json)['data'] # 用字典存储每个id对应的POK和TOK值 id_grouped = {} for item in data_list: item_id = item['id'] item_type = item['type'] # 将字符串类型的value转为整数,方便计算 item_value = int(item['value']) # 初始化当前id的存储字典 if item_id not in id_grouped: id_grouped[item_id] = {} # 只保留POK和TOK类型的数据 if item_type in ('POK', 'TOK'): id_grouped[item_id][item_type] = item_value # 计算每个id的POK - TOK差值 result = {} for id_key, type_values in id_grouped.items(): # 确保当前id同时存在POK和TOK数据,避免报错 if 'POK' in type_values and 'TOK' in type_values: result[id_key] = type_values['POK'] - type_values['TOK'] else: result[id_key] = "缺少POK或TOK数据" # 输出最终结果 print(result) # 输出结果:{'1': 2, '2': -22, '3': -22}
代码优化思路
1. 使用defaultdict简化分组逻辑
用collections.defaultdict替代普通字典,省去每次判断id是否存在的步骤,让代码更简洁:
from collections import defaultdict id_grouped = defaultdict(dict) for item in data_list: item_id = item['id'] item_type = item['type'] item_value = int(item['value']) if item_type in ('POK', 'TOK'): id_grouped[item_id][item_type] = item_value
2. 用字典推导式简化结果计算
把差值计算的循环改成字典推导式,代码更紧凑:
result = { id_key: type_values['POK'] - type_values['TOK'] if 'POK' in type_values and 'TOK' in type_values else "缺少数据" for id_key, type_values in id_grouped.items() }
3. 大数据量场景用pandas高效处理
如果你的数据量很大,用pandas的分组和透视表功能会更高效,代码也更简洁:
import pandas as pd # 转换成DataFrame df = pd.DataFrame(data_list) # 过滤出POK和TOK类型,并把value转为整数 df_filtered = df[df['type'].isin(['POK', 'TOK'])].copy() df_filtered['value'] = df_filtered['value'].astype(int) # 透视表转换:id为行,type为列,value为值 pivot_df = df_filtered.pivot(index='id', columns='type', values='value') # 计算差值 pivot_df['POK_MINUS_TOK'] = pivot_df['POK'] - pivot_df['TOK'] # 输出结果字典 print(pivot_df['POK_MINUS_TOK'].to_dict())
4. 增加数据校验
可以在处理前检查数据完整性,比如某个id缺少POK或TOK时,打印警告信息,方便排查问题:
for id_key, type_values in id_grouped.items(): if 'POK' not in type_values: print(f"警告:id {id_key} 缺少POK数据") if 'TOK' not in type_values: print(f"警告:id {id_key} 缺少TOK数据")
内容的提问来源于stack exchange,提问作者S Andrew
相关产品推荐
相关产品推荐

