将嵌套字典转换为带子列的Pandas DataFrame
嵌套字典转指定层级DataFrame的实现方案
问题描述
给定如下嵌套字典:
nest_dict = { 'Main_col1': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col2': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col3': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col4': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col5': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6} }
需要将其转换为DataFrame,要求:
sub_col系列子列以对应Main_col为上层col系列列与sub_col系列列处于同一层级,无需挂载在Main_col之下
解决方案
方案1:单一行展示所有数据
如果所有Main_col的col和sub_col值一致,可将数据合并为单行,列采用双层索引结构:
import pandas as pd # 原嵌套字典 nest_dict = { 'Main_col1': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col2': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col3': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col4': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col5': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6} } # 拆分col系列和sub_col系列数据 col_data = {k: v for k, v in nest_dict['Main_col1'].items() if not k.startswith('sub_col')} sub_data = {main_col: {k: v for k, v in items.items() if k.startswith('sub_col')} for main_col, items in nest_dict.items()} # 构造双层索引列 columns = [] # 添加col系列列(空字符串作为上层标识) for col in col_data.keys(): columns.append(('', col)) # 添加每个Main_col对应的sub_col系列列 for main_col, subs in sub_data.items(): for sub_col in subs.keys(): columns.append((main_col, sub_col)) # 构造单行数据 row_data = list(col_data.values()) for main_col in sub_data: row_data.extend(sub_data[main_col].values()) # 创建DataFrame df = pd.DataFrame([row_data], columns=pd.MultiIndex.from_tuples(columns)) print(df)
输出结果:
col col2 col3 Main_col1 Main_col2 Main_col3 Main_col4 Main_col5 1 2 3 sub_col sub_col2 sub_col3 sub_col sub_col2 sub_col3 sub_col sub_col2 sub_col3 sub_col sub_col2 sub_col3 sub_col sub_col2 sub_col3 0 1 2 3 4 5 6 4 5 6 4 5 6 4 5 6 4 5 6
方案2:按Main_col分行展示
如果需要以Main_col为行索引,仅当前行对应Main_col的sub_col有值,其余为缺失值:
import pandas as pd nest_dict = { 'Main_col1': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col2': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col3': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col4': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6}, 'Main_col5': {'col': 1, 'col2': 2, 'col3': 3, 'sub_col': 4, 'sub_col2': 5, 'sub_col3': 6} } # 定义列名分组 col_cols = ['col', 'col2', 'col3'] sub_col_names = ['sub_col', 'sub_col2', 'sub_col3'] # 构造双层索引列 columns = [] for col in col_cols: columns.append(('', col)) for main_col in nest_dict.keys(): for sub_col in sub_col_names: columns.append((main_col, sub_col)) # 构造每行数据 data = [] for main_col in nest_dict: row = [] # 添加当前行的col系列值 row.extend([nest_dict[main_col][col] for col in col_cols]) # 添加每个Main_col的sub_col值:仅当前Main_col对应位置赋值,其余为缺失值 for mc in nest_dict.keys(): if mc == main_col: row.extend([nest_dict[mc][sub] for sub in sub_col_names]) else: row.extend([pd.NA]*len(sub_col_names)) data.append(row) # 创建DataFrame并设置行索引 df = pd.DataFrame(data, index=nest_dict.keys(), columns=pd.MultiIndex.from_tuples(columns)) print(df)
输出结果:
col col2 col3 Main_col1 Main_col2 Main_col3 Main_col4 Main_col5 1 2 3 sub_col sub_col2 sub_col3 sub_col sub_col2 sub_col3 sub_col sub_col2 sub_col3 sub_col sub_col2 sub_col3 sub_col sub_col2 sub_col3 Main_col1 1 2 3 4 5 6 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> Main_col2 1 2 3 <NA> <NA> <NA> 4 5 6 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> Main_col3 1 2 3 <NA> <NA> <NA> <NA> <NA> <NA> 4 5 6 <NA> <NA> <NA> <NA> <NA> <NA> Main_col4 1 2 3 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> 4 5 6 <NA> <NA> <NA> Main_col5 1 2 3 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> 4 5 6
内容的提问来源于stack exchange,提问作者Tomasz
相关产品推荐
相关产品推荐

