如何将矩阵格式的DataFrame转换为对比值列表格式?
对称DataFrame转换为唯一比较对格式
给定如下对称DataFrame:
1 2 3 1 1 4 2 2 4 1 8 3 2 8 1
需要将其转换为包含Comparison(行与列的比较标识)和Value两列的目标格式,示例输出如下:
Comparison Value 1 v 1 1 1 v 2 4 1 v 3 2 2 v 3 8
可复现代码实现
首先构造原始DataFrame:
import pandas as pd # 原始数据 data = {1: {1: 1.0, 2: 4, 3: 2}, 2: {1: 4, 2: 1.0, 3: 8}, 3: {1: 2, 2: 8, 3: 1.0}} df = pd.DataFrame(data)
方法一:利用stack()和索引过滤
适合快速批量处理,通过堆叠DataFrame后筛选目标索引对:
# 将DataFrame堆叠为多级索引Series stacked_df = df.stack() # 筛选需要的索引对:保留(1,1)以及所有行索引 < 列索引的组合 filtered = stacked_df[ ((stacked_df.index.get_level_values(0) == 1) & (stacked_df.index.get_level_values(1) == 1)) | (stacked_df.index.get_level_values(0) < stacked_df.index.get_level_values(1)) ] # 转换为目标格式 result = filtered.reset_index() result.columns = ['Row', 'Col', 'Value'] result['Comparison'] = result['Row'].astype(str) + ' v ' + result['Col'].astype(str) result = result[['Comparison', 'Value']].reset_index(drop=True) print(result)
输出结果:
Comparison Value 0 1 v 1 1.0 1 1 v 2 4.0 2 1 v 3 2.0 3 2 v 3 8.0
方法二:手动生成索引对(更灵活)
如果需要自定义保留的比较对,用itertools生成目标索引组合后取值:
from itertools import combinations_with_replacement # 生成所有行索引 <= 列索引的组合(如需完全匹配示例,可手动指定pairs = [(1,1), (1,2), (1,3), (2,3)]) pairs = list(combinations_with_replacement(df.index, 2)) # 构造结果数据 result_rows = [] for row_idx, col_idx in pairs: result_rows.append({ 'Comparison': f"{row_idx} v {col_idx}", 'Value': df.loc[row_idx, col_idx] }) result = pd.DataFrame(result_rows) print(result)
调整说明
- 若需保留所有对角线元素(如2v2、3v3),将方法一的过滤条件改为
stacked_df.index.get_level_values(0) <= stacked_df.index.get_level_values(1)即可。 - 若不需要任何对角线元素,直接用
stacked_df.index.get_level_values(0) < stacked_df.index.get_level_values(1)作为过滤条件,会得到1v2、1v3、2v3三行。
内容的提问来源于stack exchange,提问作者Niam45
相关产品推荐
相关产品推荐

