You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现pandas同时对行、列groupby的通用自定义聚合方案

pandas二维分组聚合通用实现方案

核心思路

将二维结构的DataFrame转换为长表格式,同时基于行分组键、列分组键做分组,每个分组对应原矩阵中一块完整的二维子矩阵,将分组数据还原为子矩阵后即可直接应用任意自定义聚合逻辑,最后把聚合结果转回二维表格格式即可。

完整实现代码

依赖导入与测试数据构造

import numpy as np
import pandas as pd

# 构造和示例完全一致的测试矩阵
rng = np.random.default_rng(12345)
names = ['A'] * 2 + ['B'] *3
mat = rng.random((5, 5))
mat = mat + mat.T # 模拟对称距离矩阵
np.fill_diagonal(mat, 0) # 距离矩阵对角线为0
df = pd.DataFrame(mat, index=names, columns=names)

自定义工具函数

def triu_mean(mat):
    # 计算矩阵上三角(不含对角线)的均值
    return mat[np.triu_indices(len(mat), 1)].mean()

核心聚合实现

# 转换为长表结构,保留原始行、列标签
df_long = df.stack().rename('value').reset_index()
df_long.columns = ['row_raw', 'col_raw', 'value']

# 定义行、列分组规则,可根据需求自定义映射逻辑,这里直接复用原始标签的分组值
df_long['row_group'] = df_long['row_raw']
df_long['col_group'] = df_long['col_raw']

# 自定义分组聚合逻辑
def custom_agg(group):
    # 将一维分组数据还原为二维子矩阵
    row_cnt = group['row_raw'].nunique()
    col_cnt = group['col_raw'].nunique()
    sub_mat = group['value'].values.reshape(row_cnt, col_cnt)
    # 按需求执行不同聚合逻辑
    if group['row_group'].iloc[0] == group['col_group'].iloc[0]:
        return triu_mean(sub_mat)
    else:
        return sub_mat.mean()

# 按行、列分组同时聚合,再转回二维表格
result = df_long.groupby(['row_group', 'col_group']).apply(custom_agg).unstack()
print(result)

输出结果

A         B
A  0.649572  1.114762
B  1.114762  0.629880

方案优势

  • 完全基于pandas原生能力实现,相比双重循环性能提升明显,数据量越大优势越突出
  • 通用性极强,任意复杂的二维子矩阵聚合逻辑都可以在custom_agg函数中实现,不需要拆分为多步计算
  • 分组规则灵活,行、列的分组映射可以自由修改,适配各种分组规则需求

内容的提问来源于stack exchange,提问作者itamar kanter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:45:01