如何利用MultiIndex重塑DataFrame并完成数据填充?
解决Pandas多级索引DataFrame的数据填充问题
原始数据
| cust_id | product | cost | return price | quantity |
|---|---|---|---|---|
| 123 | pencil | 10 | 5 | 2 |
| 123 | book | 20 | 10 | 1 |
| 543 | file | 70 | 50 | 3 |
| 543 | pencil | 20 | 4 | 3 |
| 543 | book | 80 | 56 | 7 |
需求说明
需要将上述DataFrame转换为带有**MultiIndex(多级列索引)**的格式,多级列结构为[产品名, ['Apportioned','Unutilised','outstanding','Exposure']]。已创建空的多级索引DataFrame,但无法填充数据。
解决方案
以下提供两种高效的填充方式,先明确基础准备步骤:
1. 基础数据初始化
先将原始数据转为DataFrame,并提取所需的索引/列列表:
import pandas as pd # 原始数据转为DataFrame raw_data = { 'cust_id': [123, 123, 543, 543, 543], 'product': ['pencil', 'book', 'file', 'pencil', 'book'], 'cost': [10, 20, 70, 20, 80], 'return price': [5, 10, 50, 4, 56], 'quantity': [2, 1, 3, 3, 7] } df = pd.DataFrame(raw_data) # 自动提取唯一客户ID和产品列表(避免手动输入出错) cpid_list = df['cust_id'].unique().tolist() product_list = df['product'].unique().tolist()
2. 方式一:用unstack批量转换(高效推荐)
先计算多级列对应的指标值,再通过unstack直接转换为目标格式:
# 先计算每个指标列(可根据实际业务规则调整计算逻辑) df['Apportioned'] = df['cost'] * df['quantity'] df['Unutilised'] = df['return price'] * df['quantity'] df['outstanding'] = (df['cost'] - df['return price']) * df['quantity'] df['Exposure'] = df['Apportioned'] - df['Unutilised'] # 转换为多级列格式 new_df = df.set_index(['cust_id', 'product'])[['Apportioned', 'Unutilised', 'outstanding', 'Exposure']].unstack(level='product') # 调整列层级顺序,匹配目标格式的[产品名, 指标名]结构 new_df = new_df.reorder_levels([1, 0], axis=columns)[product_list]
3. 方式二:逐行循环填充(适合自定义复杂逻辑)
如果需要针对特定位置做个性化赋值,可遍历原始数据逐行填充:
# 创建空的多级索引DataFrame header = pd.MultiIndex.from_product([product_list, ['Apportioned','Unutilised','outstanding','Exposure']]) new_df = pd.DataFrame(index=cpid_list, columns=header) # 遍历原始数据,填充对应位置 for _, row in df.iterrows(): cust = row['cust_id'] prod = row['product'] # 按业务规则计算并赋值 new_df.loc[cust, (prod, 'Apportioned')] = row['cost'] * row['quantity'] new_df.loc[cust, (prod, 'Unutilised')] = row['return price'] * row['quantity'] new_df.loc[cust, (prod, 'outstanding')] = (row['cost'] - row['return price']) * row['quantity'] new_df.loc[cust, (prod, 'Exposure')] = (row['cost'] - row['return price']) * row['quantity']
注意事项
- 指标计算逻辑可根据实际业务需求修改,上述仅为示例
- 确保
cpid_list和product_list包含所有需要的行/列,避免索引不匹配 - 数据量较大时,优先使用
unstack方式,效率远高于逐行循环
内容的提问来源于stack exchange,提问作者kavyashree H.P
相关产品推荐
相关产品推荐

