如何用Pandas从DataFrame生成带额外行列的指定矩阵?
问题描述
现有一个名为sample_df的DataFrame,结构如下:
Set1 Set2 %overlap %unique for Set1 %unique for Set2 0 S 077 S2 077 98.790 0.01 0.02 1 S 080 S2 080 99.165 0.01 0.01 2 S 023 S2 023 98.490 0.01 0.02 3 S 080 S2 115 97.760 0.02 0.03
需要生成一个5x5矩阵,要求:
- 以Set2的值为列名,列名下方一行对应填充
%unique for Set2的对应值 - Set1的每个值旁添加一列,填充对应
%unique for Set1的值 - 矩阵其余对角线位置填充
%overlap的对应值
期望结果如下:
S2 077 S2 080 S2 023 S2 115 0.02 0.01 0.02 0.03 S 077 0.01 98.790 S 080 0.01 99.165 S 023 0.01 98.490 S 080 0.02 97.760
目前使用sub_df = sample_df.pivot(index='Set1', columns='Set2', values='%overlap')生成新DataFrame,但Set1的重复值"S 080"仅显示一行,同时对应两列值,不符合需求。需要实现目标的简单方法。
解决方法
由于Set1存在重复值,直接使用pivot会合并相同Set1的行,导致重复条目丢失。我们可以通过保留原始行索引、分步构造矩阵来实现需求:
步骤1:构建重叠值矩阵
以原始DataFrame的行索引作为唯一标识,避免合并重复的Set1条目:
overlap_matrix = sample_df.pivot(index=sample_df.index, columns='Set2', values='%overlap')
步骤2:添加Set1和对应唯一值列
将Set1和%unique for Set1列合并到矩阵左侧:
import pandas as pd import numpy as np result = pd.concat([sample_df[['Set1', '%unique for Set1']], overlap_matrix], axis=1)
步骤3:添加Set2的唯一值表头行
提取Set2对应的%unique for Set2值,构造表头行并插入到结果顶部:
# 获取Set2与对应唯一值的映射 set2_unique_map = sample_df.drop_duplicates(subset='Set2').set_index('Set2')['%unique for Set2'] # 构造表头行数据,前两列留空 header_data = [np.nan, np.nan] + [set2_unique_map.get(col, np.nan) for col in result.columns[2:]] header_row = pd.Series(header_data, index=result.columns).to_frame().T # 合并表头行与结果矩阵 result = pd.concat([header_row, result], ignore_index=True)
步骤4:优化列名显示(可选)
如果需要更清晰的多级列名格式,可以设置:
# 构造多级列名 top_level = ['', ''] + list(set2_unique_map.index) bottom_level = ['Set1', '%unique for Set1'] + ['%overlap']*len(set2_unique_map) result.columns = pd.MultiIndex.from_tuples(zip(top_level, bottom_level))
执行完以上代码后,得到的result就是符合需求的矩阵,重复的S 080条目会保留各自的行,对应%overlap值也会放在正确的列位置。
内容的提问来源于stack exchange,提问作者chan-98
相关产品推荐
相关产品推荐

