如何将相关矩阵值存入DataFrame并解决melt的KeyError问题
问题描述
现有如下结构的DataFrame:
| A | B | C | name | |
|---|---|---|---|---|
| 0 | 0.5 | 0 | 8 | test1 |
| 1 | 5.0 | 1 | 5 | test2 |
| 2 | 3.0 | 2 | 6 | test3 |
| 3 | 6.0 | 3 | 10 | test4 |
| 4 | 18.0 | 14 | 12 | test5 |
需求是按name分组,计算A、B、C列间的相关矩阵,仅保留无重复的上三角部分(排除对角线),最终转化为如下结构的DataFrame:
| Var1_Var2 | Value | name | |
|---|---|---|---|
| 0 | (A,B) | 0.2 | test1 |
| 1 | (A,B) | 0.8 | test2 |
| 2 | (A,B) | 0.23 | test3 |
| 3 | (B,C) | 0.9 | test1 |
| 4 | (B,C) | 0.4 | test2 |
| 5 | (B,C) | 0.4 | test3 |
| 6 | (C,A) | 0.4 | test1 |
| 7 | (C,A) | 0.4 | test2 |
| 8 | (C,A) | 0.4 | test3 |
用户尝试循环分组计算相关矩阵后,生成的dft列索引为元组类型(如('A', 'B')、('name', 'name')),但使用pd.melt时传入字符串'(name, name)'作为id_vars,触发KeyError。
错误原因
dft的列是元组索引,不是字符串。传入的id_vars=['(name, name)']是字符串格式,和实际的元组列名('name', 'name')不匹配,导致无法找到对应列。
解决方法
方法1:修复现有dft的melt操作
直接用元组匹配列名,后续再调整列格式:
# 使用元组作为id_vars参数匹配列名 melted = dft.melt(id_vars=[('name', 'name')], var_name="Var1_Var2", value_name="Value") # 重命名列并整理格式 melted = melted.rename(columns={('name', 'name'): 'name'}) # 可选:将元组类型的Var1_Var2转为字符串格式 melted['Var1_Var2'] = melted['Var1_Var2'].apply(lambda x: f"({x[0]},{x[1]})")
方法2:更高效的分组实现(推荐)
避免循环append(效率低下),直接用groupby结合自定义函数一步生成目标结果:
import pandas as pd import numpy as np def process_group(group): # 仅计算A、B、C的相关矩阵 corr = group[['A', 'B', 'C']].corr() # 提取上三角区域(k=1排除对角线) triu_corr = corr.where(np.triu(np.ones(corr.shape), k=1).astype(bool)) # 堆叠成Series并过滤空值 stacked = triu_corr.stack().reset_index(name='Value') # 合并变量对列 stacked['Var1_Var2'] = stacked.apply(lambda row: f"({row['level_0']},{row['level_1']})", axis=1) # 添加分组的name值 stacked['name'] = group['name'].iloc[0] # 保留需要的列 return stacked[['Var1_Var2', 'Value', 'name']] # 分组处理并合并结果 result = df.groupby('name').apply(process_group).reset_index(drop=True)
该方法直接生成目标结构,无需后续melt操作,代码更简洁且效率更高。
内容的提问来源于stack exchange,提问作者Art
相关产品推荐
相关产品推荐

