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

如何用pandas pivot_table聚合布尔值列并生成特定统计矩阵?

用Pivot Table实现自定义统计矩阵方案

当然可以用pivot_table实现你要的统计矩阵,不过需要先补充全局和各类汇总的统计数据,再调整结构适配你要的格式。咱们一步步来操作:

第一步:还原原始数据

先把你给出的DataFrame还原出来,方便后续操作:

import pandas as pd
import numpy as np

data = {
    'code': [1000, 1000, 1000, 1000, 2000, 2000, 2000, 2000, 2000],
    'y_m': [201701, 201701, 201702, 201702, 201701, 201701, 201702, 201702, 201702],
    'has_id': [True, False, True, True, True, False, False, False, True]
}
df = pd.DataFrame(data)

第二步:计算所有需要的占比统计

你的需求里不仅有code+y_m的分组占比,还需要全局、单独code、单独y_m的占比,所以要把这些统计都算出来:

  1. 基础分组占比(你已经实现的部分):
grouped = df.groupby(['code', 'y_m'])['has_id'].apply(lambda x: np.sum(x)/len(x)).reset_index(name='pct_with_id')
  1. 单独code的全局占比(不区分y_m):
code_total = df.groupby('code')['has_id'].apply(lambda x: np.sum(x)/len(x)).reset_index(name='pct_with_id')
code_total['y_m'] = 'total'  # 标记为code总计
  1. 单独y_m的全局占比(不区分code):
ym_total = df.groupby('y_m')['has_id'].apply(lambda x: np.sum(x)/len(x)).reset_index(name='pct_with_id')
ym_total['code'] = 'total'  # 标记为y_m总计
  1. 全量数据的占比:
global_total = pd.DataFrame({
    'code': ['total'],
    'y_m': ['total'],
    'pct_with_id': [df['has_id'].sum()/len(df)]
})
  1. 合并所有统计数据:
combined = pd.concat([grouped, code_total, ym_total, global_total], ignore_index=True)

第三步:用Pivot Table生成基础透视表

现在用pivot_table把合并后的数据转换成透视表,同时用-1填充缺失值:

pivot = combined.pivot_table(index='code', columns='y_m', values='pct_with_id', fill_value=-1)

这时候得到的透视表结构如下:

code201701201702total
10000.51.00.75
20000.50.333...0.4
total0.50.60.555...

第四步:调整成目标矩阵格式

最后我们需要把透视表调整成你要的带占位符和特殊行列的结构:

# 创建目标矩阵的空结构
result = pd.DataFrame(index=[0,1,2,3], columns=[0,1,2,3])

# 填充0行(表头行)
result.loc[0] = [-1, 0, 201701, 201702]

# 填充0列(行标识列)
result.loc[1, 0] = 0
result.loc[2, 0] = 1000
result.loc[3, 0] = 2000

# 填充全局统计行(行1)
result.loc[1, 1] = round(global_total['pct_with_id'].values[0], 2)  # 全量占比≈0.56
result.loc[1, 2] = ym_total[ym_total['y_m']==201701]['pct_with_id'].values[0]  # 201701占比0.5
result.loc[1, 3] = ym_total[ym_total['y_m']==201702]['pct_with_id'].values[0]  # 201702占比0.6

# 填充code=1000的统计行(行2)
result.loc[2, 1] = code_total[code_total['code']==1000]['pct_with_id'].values[0]  # 0.75
result.loc[2, 2] = grouped[(grouped['code']==1000)&(grouped['y_m']==201701)]['pct_with_id'].values[0]  # 0.5
result.loc[2, 3] = grouped[(grouped['code']==1000)&(grouped['y_m']==201702)]['pct_with_id'].values[0]  # 1.0

# 填充code=2000的统计行(行3)
result.loc[3, 1] = code_total[code_total['code']==2000]['pct_with_id'].values[0]  # 0.4
result.loc[3, 2] = grouped[(grouped['code']==2000)&(grouped['y_m']==201701)]['pct_with_id'].values[0]  # 0.5
result.loc[3, 3] = round(grouped[(grouped['code']==2000)&(grouped['y_m']==201702)]['pct_with_id'].values[0], 2)  # ≈0.33

运行后得到的result就是你要的统计矩阵啦:

0     1       2       3
0  -1     0  201701  201702
1   0  0.56     0.5     0.6
2 1000  0.75     0.5     1.0
3 2000   0.4     0.5    0.33

简单来说,pivot_table帮我们完成了核心的分组透视工作,剩下的就是补充汇总数据和调整格式,完全可以满足你的需求~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:30:47