提取DataFrame嵌套列元素并存储为新列的方法
解决嵌套字典列展开为多列的问题
我来帮你搞定这个嵌套数据展开的需求!你现在的问题是要把d列里的顶层字段(cases、suspects、negative)和嵌套的stats列表都展开成单独的列,原来的循环因为是把每个stat拆成新行,所以没法得到你想要的宽表格式。下面是具体的解决方案:
步骤说明
我们可以分三步完成这个任务:
- 提取
d列中的顶层字段(不需要嵌套的部分) - 把
stats列表转换为宽格式的列(每个diag+sex组合对应一列) - 将两部分数据合并,对齐原始行的索引
完整代码示例
import pandas as pd # 你的原始数据 myDF = pd.DataFrame.from_dict({'id': {0: '403', 1: '402', 2: '401'}, 'd': {0: {'cases': 1, 'suspects': 22, 'negative': 0, 'stats': [{'diag': 'casesELISA', 'sex': 'F', 'cases': 1}, {'diag': 'suspects', 'sex': 'M', 'cases': 11}, {'diag': 'suspects', 'sex': 'F', 'cases': 10}, {'diag': 'suspectsPCR', 'sex': 'F', 'cases': 1}]}, 1: {'cases': 0, 'suspects': 18, 'negative': 0, 'stats': [{'diag': 'suspects', 'sex': 'M', 'cases': 9}, {'diag': 'suspects', 'sex': 'F', 'cases': 9}]}, 2: {'cases': 0, 'suspects': 31, 'negative': 0, 'stats': [{'diag': 'suspects', 'sex': 'M', 'cases': 12}, {'diag': 'suspects', 'sex': 'F', 'cases': 18}, {'diag': 'suspectsPCR', 'sex': 'M', 'cases': 1}]}}}) # 步骤1:提取d列的顶层字段(cases、suspects、negative) top_level_data = pd.json_normalize(myDF['d']).drop('stats', axis=1) # 步骤2:处理stats列表,转换为宽格式列 # 先把每个行的stats拆成单独行,同时保留原始索引 stats_exploded = myDF['d'].apply(lambda x: x['stats']).explode().apply(pd.Series) stats_exploded = stats_exploded.reset_index().rename(columns={'index': 'original_row_index'}) # 生成自定义列名(和你期望的格式匹配) stats_exploded['column_name'] = 'diag_' + stats_exploded['diag'] + '_sex_' + stats_exploded['sex'] # 转成宽表:每个原始行对应一行,列是自定义的column_name,值是cases stats_wide = stats_exploded.pivot( index='original_row_index', columns='column_name', values='cases' ) # 步骤3:合并所有数据,包括原始id列 final_result = pd.concat([myDF['id'], top_level_data, stats_wide], axis=1) # 查看结果 print(final_result)
输出结果
运行后你会得到和你期望格式一致的DataFrame,缺失的数值会显示为NaN(对应你期望的NA):
id cases suspects negative diag_casesELISA_sex_F diag_suspects_sex_M diag_suspects_sex_F diag_suspectsPCR_sex_F diag_suspectsPCR_sex_M 0 403 1 22 0 1.0 11.0 10.0 1.0 NaN 1 402 0 18 0 NaN 9.0 9.0 NaN NaN 2 401 0 31 0 NaN 12.0 18.0 NaN 1.0
为什么原来的代码不行?
你原来的循环会把每个stat条目和原始行合并成新行,这样会生成多行数据(比如第一行原始数据会生成4行),而我们需要的是每行对应一个原始id,把所有stat的内容展开为列,所以用pivot转成宽表才是正确的思路。
内容的提问来源于stack exchange,提问作者user113156
相关产品推荐
相关产品推荐

