Python嵌套JSON转CSV/DataFrame:解决单一条目嵌套输出重复问题
我懂你现在的困扰——单个深层嵌套的JSON转DataFrame时老是冒出重复行对吧?咱们先拆解下你的JSON结构,再一步步搞定这个问题。
你的JSON外层是个只有1个元素的数组,这个元素里包着两个核心数组:questions(存问答对)和transactions(存账户信息)。直接用默认的json_normalize会因为同时展开两个数组产生笛卡尔积,这就是重复的根源。
下面给你两种常用的解决方案,按需选就行:
方案1:把questions转成列,和transactions合并成单行数据
如果希望把每个question的key作为列名,最终得到一行包含所有信息的DataFrame,可以这么写代码:
import pandas as pd # 你的JSON数据 data = [{ "questions": [{ "key": "years-age", "responseKey": None, "responseText": "27", "responseKeys": None }, { "key": "gender", "responseKey": "male", "responseText": None, "responseKeys": None } ], "transactions": [{ "accId": "v1BN3o9Qy9i..." }] }] # 处理questions:转成宽表格式 questions_df = pd.DataFrame(data[0]['questions']).set_index('key')[['responseText', 'responseKey']].unstack().reset_index(drop=True) # 给列名加前缀,避免重复混淆 questions_df.columns = [f"{col[1]}_{col[0]}" for col in questions_df.columns] # 处理transactions:转成DataFrame transactions_df = pd.DataFrame(data[0]['transactions']) # 合并两个DataFrame final_df = pd.concat([transactions_df, questions_df], axis=1) print(final_df)
输出结果是一行数据,包含accId、responseText_years-age、responseKey_years-age、responseText_gender、responseKey_gender这些列,完全没有重复。
方案2:保留每个question的行,关联transactions信息
如果需要保留每个question的独立行,同时带上对应的账户信息,可以用json_normalize指定展开路径,避开笛卡尔积:
import pandas as pd data = [{ "questions": [{ "key": "years-age", "responseKey": None, "responseText": "27", "responseKeys": None }, { "key": "gender", "responseKey": "male", "responseText": None, "responseKeys": None } ], "transactions": [{ "accId": "v1BN3o9Qy9i..." }] }] # 指定只展开questions数组,把transactions作为元数据保留 df = pd.json_normalize(data, record_path='questions', meta=['transactions']) # 展开transactions数组(因为它是嵌套的数组结构) df = df.explode('transactions').reset_index(drop=True) # 把transactions里的字典转成单独的列 df = pd.concat([df.drop('transactions', axis=1), df['transactions'].apply(pd.Series)], axis=1) print(df)
这样得到的是2行数据,每行对应一个question,同时带上accId,不会出现重复——因为我们只展开了questions数组,transactions是作为元数据关联到每一行的,而不是和questions做笛卡尔积。
为什么会出现重复?
如果你直接用pd.json_normalize(data)不指定参数,函数会自动识别所有嵌套数组并展开,相当于把questions和transactions做笛卡尔积。比如你的questions有2条,transactions有1条,就会生成2×1=2行;如果transactions有3条,就会生成6行,这就是你看到的重复现象。
内容的提问来源于stack exchange,提问作者user9116643

