如何基于Pandas DataFrame生成行间差值矩阵?
问题描述
现有如下Pandas DataFrame:
import pandas as pd df = pd.DataFrame({'Subject': ['Alpha', 'Bravo', 'Charlie'], 'Total': [31.05590, 32.91925, 36.02484]})
对应的原始数据表格:
| Subject | Total |
|---|---|
| Alpha | 31.05590 |
| Bravo | 32.91925 |
| Charlie | 36.02484 |
需要生成一个行间差值矩阵,即矩阵中每个位置(i,j)的值为第i行Subject的Total值减去第j行Subject的Total值,例如:
Alpha-Charlie = Alpha(Total) - Charlie(Total) -> (31.05590 - 36.02484) = -4.96894
Bravo-Alpha = Bravo(Total) - Alpha(Total) -> (32.91925 - 31.05590) = 1.86335
预期输出表格:
| Subject | Alpha | Bravo | Charlie |
|---|---|---|---|
| Alpha | 0.00000 | -1.86335 | -4.96894 |
| Bravo | 1.86335 | 0.00000 | -3.10559 |
| Charlie | 4.96894 | 3.10559 | 0.00000 |
尝试了以下代码,但得到的是对角矩阵,无法满足需求:
import numpy as np ct_a = pd.crosstab(df['Subject'], df['Subject'], values=df['Total'], aggfunc=np.sum).fillna(0) ct_a.to_csv('data/ct_a.csv', index=True)
解决方案
方法1:利用广播运算实现
将Total列转换为二维数组后,直接用行向量减去列向量实现广播,再包装成DataFrame:
# 提取Total值并转为二维数组 values = df['Total'].values.reshape(-1, 1) # 计算行减列的差值 diff_matrix = values - values.T # 构建结果DataFrame result = pd.DataFrame(diff_matrix, index=df['Subject'], columns=df['Subject']) # 保留5位小数(和预期格式一致) result = result.round(5)
方法2:使用Pandas的subtract方法
通过将Total列分别作为索引和列的Series,调用subtract方法实现元素级差值计算:
# 创建以Subject为索引的Series s = df.set_index('Subject')['Total'] # 计算差值:行索引对应的值减去列索引对应的值 result = s.subtract(s, axis=0).round(5)
方法3:外连接后计算差值
通过自身外连接,再计算每行的Total差值:
# 自身外连接,添加后缀区分左右表 merged = df.merge(df, how='outer', suffixes=('_x', '_y')) # 计算差值 merged['diff'] = merged['Total_x'] - merged['Total_y'] # 重塑为矩阵形式 result = merged.pivot(index='Subject_x', columns='Subject_y', values='diff').round(5) # 重命名索引和列名 result.index.name = 'Subject' result.columns.name = 'Subject'
运行上述任意一种方法后,都能得到符合预期的差值矩阵,保存为CSV的话直接执行result.to_csv('data/diff_matrix.csv', index=True)即可。
内容的提问来源于stack exchange,提问作者matekus
相关产品推荐
相关产品推荐

