如何用Python提取多JSON文件所有键并生成标记DataFrame
需求描述
假设有n个JSON文件,以下是4个示例:
示例JSON文件
path/file1.json
{"keyA":"valueA", "keyB":"valueB", "keyC":"valueC", "keyD":{ "keyD_1":"valueD_1", "KeyD_2":"valueD_2" } }
path/file2.json
{"keyB":"valueB", "keyC":"valueC", "keyD":{ "KeyD_2":"valueD_2" } }
path/file3.json
{"keyA":"valueA", "keyB":"valueB", "keyD":{ "keyD_1":"valueD_1", "KeyD_2":"valueD_2" } }
path/file4.json
{"keyB":"valueB", "keyD":{ "KeyD_1":"valueD_1" } }
需要用Python生成一个DataFrame表格,要求:
- 以文件名作为行索引
- 以所有JSON中出现的**所有键(包括嵌套键)**作为列
- 文件包含对应键则该行该列值为1,否则为0
预期输出示例:
file_name keyA keyB keyC keyD keyD_1 keyD_2 file1.json 1 1 1 1 1 1 file2.json 0 1 1 1 0 1 file3.json 1 1 0 1 1 1 file4.json 0 1 0 1 1 0 (...) (...) (...) (...) (...) (...) (...)
实现方案
核心思路
- 遍历所有JSON文件,递归提取所有层级的键(包括嵌套字典中的键),汇总得到所有可能的列名
- 逐个检查每个文件是否包含这些键,生成1/0的标记数据
- 将所有文件的标记数据组合成DataFrame,调整格式后输出
代码实现
import json import os import pandas as pd def extract_all_keys(data): """递归提取JSON中所有层级的键""" keys = [] if isinstance(data, dict): for k, v in data.items(): keys.append(k) # 如果值是字典,继续递归提取子键 if isinstance(v, dict): keys.extend(extract_all_keys(v)) return keys def get_file_key_status(file_path, all_keys): """检查单个文件中各键的存在情况,返回标记字典""" with open(file_path, 'r', encoding='utf-8') as f: data = json.load(f) # 获取当前文件的所有键 file_keys = extract_all_keys(data) # 生成1/0标记 status = {key: 1 if key in file_keys else 0 for key in all_keys} # 添加文件名 status['file_name'] = os.path.basename(file_path) return status # ---------------------- 配置与执行 ---------------------- # 替换为你的JSON文件所在目录 json_directory = 'path' # 1. 获取目录下所有JSON文件路径 json_files = [ os.path.join(json_directory, filename) for filename in os.listdir(json_directory) if filename.endswith('.json') ] # 2. 收集所有出现过的键 all_keys = set() for file_path in json_files: with open(file_path, 'r', encoding='utf-8') as f: data = json.load(f) all_keys.update(extract_all_keys(data)) # 转换为有序列表 all_keys = sorted(list(all_keys)) # 3. 生成每个文件的键存在状态 data_rows = [get_file_key_status(file, all_keys) for file in json_files] # 4. 构建DataFrame并调整格式 df = pd.DataFrame(data_rows) df = df.set_index('file_name') # 可选:按预期输出调整列顺序(如果需要固定顺序) desired_columns = ['keyA', 'keyB', 'keyC', 'keyD', 'keyD_1', 'keyD_2'] # 保留存在的列,剩余列追加到后面 existing_cols = [col for col in desired_columns if col in df.columns] remaining_cols = [col for col in df.columns if col not in existing_cols] df = df[existing_cols + remaining_cols] # 输出结果 print(df.to_string()) # 可选:保存到CSV文件 # df.to_csv('json_key_presence.csv', sep='\t')
注意事项
- 键名大小写敏感:如果JSON中存在
keyD_1和KeyD_1这类大小写差异的键,会被视为不同列。若需要统一大小写,可在extract_all_keys函数中把键转换为小写(比如keys.append(k.lower())) - 数组处理:当前代码不会提取数组中的键,若JSON包含数组且需要处理其中的键,可修改
extract_all_keys函数,增加对列表类型的遍历逻辑
内容的提问来源于stack exchange,提问作者NigelBlainey
相关产品推荐
相关产品推荐

