从JSON生成字典时值丢失问题排查
解决字典列表合并时的值丢失问题
我明白你遇到的麻烦了——你想把按连接名分组的字段列表合并成一个大字典,但之前的方法要么生成了一堆小字典,要么合并时覆盖了之前的值,导致大量数据丢失。咱们一步步来找出问题并解决它:
首先,先简化你处理Query Fields Used的代码
你之前的循环写法太繁琐了,用Pandas的apply方法可以更简洁地完成字段清洗:
import re import pandas as pd # 你的原始JSON数据 json_data = [ {"Query Fields Used":None,"History Connection Name":None,"History Query Run Count":"138,036"}, {"Query Fields Used":"[\"shifts.date_date\", \"shifts.sum_booked_shifts\"]","History Connection Name":"sandy","History Query Run Count":"59,069"}, {"Query Fields Used":"[\"daily_supply_v2.sum_booked_shifts\", \"daily_supply_v2.date_date\"]","History Connection Name":"low","History Query Run Count":"50,259"}, {"Query Fields Used":"[\"daily_supply_v2.date_date\", \"daily_supply_v2.sum_booked_shifts\"]","History Connection Name":"sandy","History Query Run Count":"50,235"}, {"Query Fields Used":"[\"orders.count_loads\", \"orders.complete_timestamp_date\"]","History Connection Name":"sandy","History Query Run Count":"29,658"}, {"Query Fields Used":"[\"hitch_stack.date_date\", \"hitch_stack.hitch_count\"]","History Connection Name":"low","History Query Run Count":"24,928"} ] # 导入数据 looker = pd.read_json(pd.io.json.dumps(json_data)) # 定义字段处理函数 def clean_fields(field_val): if pd.isna(field_val): return ["None"] # 移除特殊字符,拆分后去除首尾空格 cleaned_str = re.sub(r'[^a-zA-Z0-9_.,]', '', field_val) return [item.strip() for item in cleaned_str.split(",")] # 应用到列上 looker['Query Fields Used'] = looker['Query Fields Used'].apply(clean_fields)
为什么你之前的方法会丢失值?
你用[{key: val} for key, val in zip(...)]生成的是多个单键小字典的列表,比如:
# 这是你生成的d的样子 [ {None: ["None"]}, {"sandy": ["shifts.date_date", "shifts.sum_booked_shifts"]}, {"low": ["daily_supply_v2.sum_booked_shifts", "daily_supply_v2.date_date"]}, ... ]
当你用funcy.merge(*d)这类工具合并时,它的逻辑是后面的字典会覆盖前面相同键的值——比如sandy出现三次,最终只会保留最后一次的字段列表,前面的两次都会被覆盖,这就是你看到值丢失的核心原因!
正确的合并方式:按连接名分组收集所有值
我们需要的是把相同连接名对应的所有字段列表累加/合并,而不是覆盖。这里有两种简单的实现方式:
方法1:用Pandas的groupby(推荐)
直接按History Connection Name分组,把所有对应的Query Fields Used收集起来:
# 收集所有字段(包含重复) merged_dict = looker.groupby('History Connection Name')['Query Fields Used'].sum().to_dict() # 如果需要去重后的字段列表 def collect_unique(fields_list): all_fields = [] for sublist in fields_list: all_fields.extend(sublist) return list(set(all_fields)) merged_unique_dict = looker.groupby('History Connection Name')['Query Fields Used'].apply(collect_unique).to_dict()
方法2:手动遍历构建字典
如果你不想用Pandas的groupby,也可以手动循环构建:
merged_dict = {} for conn_name, fields in zip(looker['History Connection Name'], looker['Query Fields Used']): # 处理null的连接名,统一命名为"None" key = conn_name if not pd.isna(conn_name) else "None" if key not in merged_dict: merged_dict[key] = [] # 把当前字段列表添加到对应的键下 merged_dict[key].extend(fields) # 同样,要去重的话可以用集合: merged_unique_dict = {} for conn_name, fields in zip(looker['History Connection Name'], looker['Query Fields Used']): key = conn_name if not pd.isna(conn_name) else "None" if key not in merged_unique_dict: merged_unique_dict[key] = set() merged_unique_dict[key].update(fields) # 把集合转回列表 merged_unique_dict = {k: list(v) for k, v in merged_unique_dict.items()}
这样得到的字典就会包含每个连接名对应的所有字段值,不会再出现丢失的情况了。
内容的提问来源于stack exchange,提问作者Basalty
相关产品推荐
相关产品推荐

