You need to enable JavaScript to run this app. 如何从扁平DataFrame计算交叉总和用于生成Seaborn热图
优惠活动
大模型
产品
解决方案
定价
更多

如何从扁平DataFrame计算交叉总和用于生成Seaborn热图

实现步骤

1. 预处理基础数据

首先修正示例中set_index未赋值的小问题,保留歌曲维度的明细结构:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

demo_df = pd.DataFrame([
    ("Get Back", 1,0,2),
    ("Help", 5, 2, 0),
    ("Let It Be", 0,2,2)
],columns=["Song","John", "Paul", "Ringo"])
# 正确设置歌曲为行索引
item_df = demo_df.set_index("Song")
# 提取所有人员列名作为交叉表的行/列表头
people_list = item_df.columns.tolist()

2. 计算两两人员的共有项总贡献

核心计算逻辑:逐行遍历每一首歌曲,识别出对该歌曲有非零贡献的人员,对这些人员的两两组合,把两人在该歌曲上的贡献值之和累加到对应的交叉格子中,最终生成对称矩阵:

# 初始化全零的对称结果矩阵
overlap_matrix = pd.DataFrame(
    np.zeros((len(people_list), len(people_list))),
    index=people_list,
    columns=people_list
)

# 逐行计算每首歌对交叉格子的贡献
for _, row in item_df.iterrows():
    # 筛选当前行中对该歌曲有非零贡献的人员
    active_people = row[row > 0].index.tolist()
    # 遍历活跃人员的所有两两组合
    for i in range(len(active_people)):
        for j in range(i+1, len(active_people)):
            p1, p2 = active_people[i], active_people[j]
            current_contribution = row[p1] + row[p2]
            # 对称矩阵两个方向的格子同步累加
            overlap_matrix.loc[p1, p2] += current_contribution
            overlap_matrix.loc[p2, p1] += current_contribution

# 将对角线(自身与自身的交叉位)设置为空值,匹配示例格式
np.fill_diagonal(overlap_matrix.values, np.nan)

计算完成后的矩阵和目标格式完全一致:

John Paul Ringo
John    NaN  7.0  3.0
Paul    7.0  NaN  4.0
Ringo   3.0  4.0  NaN

3. 用Seaborn绘制热图

直接把计算好的对称矩阵传入Seaborn热图接口,通过mask参数隐藏对角线的空值即可:

sns.heatmap(
    overlap_matrix,
    annot=True,
    fmt=".0f",
    cmap="Blues",
    mask=overlap_matrix.isna()
)
plt.title("人员间共有项贡献值")
plt.show()

常见卡点说明

之前尝试用groupby+unstack方案没跑通的核心原因:这类长表聚合逻辑天然缺少“判断两人是否同时在单条记录上有非零值”的前置筛选步骤,直接做交叉聚合会把单人贡献的数值也计入重叠值,导致结果和预期偏差。


内容的提问来源于stack exchange,提问作者Phil Sheard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 22:36:04