如何合并两个JSON文件并仅保留指定非空对象?
合并指定JSON对象并排除冗余空对象
需求说明
有两个结构相似的JSON文件,核心结构如下:
{"biosample": {"id": "xxxx"}, "wgs_qc_metrics": {"aln_metrics": {}, "variant_metrics": {}}}
需要实现:
- 仅合并指定对象:保留data1的
aln_metrics和data2的variant_metrics - 排除冗余空对象:已知data1的
variant_metrics和data2的aln_metrics始终为空,输出中要排除这些空对象 - 保留data1的
biosample信息,不能让data2的空aln_metrics覆盖data1的有效数据
输入文件示例
File1.json
{ "biosample": { "id": "NA12878" }, "wgs_qc_metrics": { "aln_metrics": { "insert_size_std_deviation": "98.2", "mad_autosome_coverage": "0", "mean_autosome_coverage": "0.00", "mean_insert_size": "447.3", "pct_autosomes_15x": "0.00", "pct_reads_mapped": "99.63", "pct_reads_properly_paired": "97.9", "yield_bp_q30": "1996315" }, "variant_metrics": {} } }
File2.json
{ "biosample": { "id": "NA12878-chr14-AKT1" }, "wgs_qc_metrics": { "aln_metrics": {}, "variant_metrics": { "count_deletions": 848, "count_insertions": 850, "count_snvs": 8489, "ratio_heterozygous_homzygous_indel": 1.49, "ratio_heterozygous_homzygous_snv": 1.05, "ratio_insertion_deletion": 1.0, "ratio_transitions_transversions_snv": 2.13 } } }
之前的错误尝试
最初用字典解包合并wgs_qc_metrics,会导致data2的空aln_metrics覆盖data1的有效数据:
json.dump({"biosample": data1["biosample"], "wgs_qc_metrics": {**data1["wgs_qc_metrics"], **data2["wgs_qc_metrics"]}}, f, sort_keys=True, indent=4)
生成的输出中aln_metrics变成空对象,不符合预期。
后续尝试的代码存在拼写错误(varinat_metrics应为variant_metrics),且路径错误(直接取data1["aln_metrics"]而非data1["wgs_qc_metrics"]["aln_metrics"]),无法正确运行。
修正后的解决方案
直接基于data1的结构,将data2的有效variant_metrics替换或更新到data1的对应位置,这样既保留data1的所有有效数据,又注入data2的有效内容:
import json import argparse def load_json(file_path): with open(file_path, 'r') as f: return json.load(f) def save_merged_json(data1, data2, outfile): # 用data2的variant_metrics替换data1的空对象 data1['wgs_qc_metrics']['variant_metrics'] = data2['wgs_qc_metrics']['variant_metrics'] # 也可以用update,效果一样(因为data1的variant_metrics是空的) # data1['wgs_qc_metrics']['variant_metrics'].update(data2['wgs_qc_metrics']['variant_metrics']) with open(outfile, "w") as f: json.dump(data1, f, sort_keys=True, indent=4) f.write("\n") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--input-aln-metrics", required=True, help="Path to File1.json") parser.add_argument("--input-variants-metrics", required=True, help="Path to File2.json") parser.add_argument("--output-json", required=True, help="Path to merged output JSON") args = parser.parse_args() aln_data = load_json(args.input_aln_metrics) variant_data = load_json(args.input_variants_metrics) save_merged_json(aln_data, variant_data, args.output_json)
代码说明
load_json函数统一处理JSON文件加载,简化代码结构- 在
save_merged_json中,直接将data2的variant_metrics赋值给data1的对应字段,因为data1的该字段原本是空对象,赋值后直接替换为有效数据 - 最终保存修改后的data1,自然保留了data1的
biosample和aln_metrics,同时加入了data2的variant_metrics,且没有空对象残留
预期输出
{ "biosample": { "id": "NA12878" }, "wgs_qc_metrics": { "aln_metrics": { "insert_size_std_deviation": "98.2", "mad_autosome_coverage": "0", "mean_autosome_coverage": "0.00", "mean_insert_size": "447.3", "pct_autosomes_15x": "0.00", "pct_reads_mapped": "99.63", "pct_reads_properly_paired": "97.9", "yield_bp_q30": "1996315" }, "variant_metrics": { "count_deletions": 848, "count_insertions": 850, "count_snvs": 8489, "ratio_heterozygous_homzygous_indel": 1.49, "ratio_heterozygous_homzygous_snv": 1.05, "ratio_insertion_deletion": 1.0, "ratio_transitions_transversions_snv": 2.13 } } }
内容的提问来源于stack exchange,提问作者user3214212
相关产品推荐
相关产品推荐

