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

在Pandas透视表中基于DataFrame单字段按行展示各列占比

问题:将透视表计数转换为行内占比百分比

现有示例DataFrame及透视表代码如下:

import pandas as pd

d = {
  "year": [2021, 2021, 2021, 2021, 2022, 2022, 2022, 2023, 2023, 2023, 2023],
  "type": ["A", "B", "B", "A", "A", "B", "A", "B", pd.NA, "B", "A"],
  "observation": [22, 11, 67, 44, 2, 16, 78, 9, 10, 11, 45]
}
df = pd.DataFrame(d)

df_pivot = pd.pivot_table(
  df,
  values="observation",
  index="year",
  columns="type",
  aggfunc="count"
)

当前透视表按count聚合得到各年份下A、B类型的计数结果:

type  A  B
year      
2021  2  2
2022  2  1
2023  1  2

需求:将上述计数替换为各类型计数占该行总数(A+B计数和)的百分比,计算时忽略type为NA的行,每行总数可能不同,期望输出如下:

type     A     B
year      
2021  0.50  0.50
2022  0.66  0.33
2023  0.33  0.66

解决方案

方法1:先过滤NA,透视计数后计算行占比

先过滤掉type为NA的行,生成计数透视表后,用每行的计数除以该行总和得到占比,最后保留两位小数:

# 过滤type为NA的行
df_filtered = df.dropna(subset=["type"])

# 生成计数透视表
df_pivot_count = pd.pivot_table(
    df_filtered,
    values="observation",
    index="year",
    columns="type",
    aggfunc="count"
)

# 计算行内占比并保留两位小数
df_desired_output = df_pivot_count.div(df_pivot_count.sum(axis=1), axis=0).round(2)

print(df_desired_output)

方法2:用groupby + value_counts(normalize=True)一步到位

按年份分组后,对type列直接使用value_counts(normalize=True)得到组内占比,再通过unstack转换为透视表格式:

df_desired_output = (
    df.dropna(subset=["type"])
      .groupby("year")["type"]
      .value_counts(normalize=True)
      .unstack(fill_value=0)
      .round(2)
)

print(df_desired_output)

方法3:分组计数后计算占比

先统计每个year-type组合的计数,再计算行内占比:

# 统计year-type的计数
counts = df.dropna(subset=["type"]).groupby(["year", "type"]).size().unstack()

# 计算行占比
df_desired_output = counts.div(counts.sum(axis=1), axis=0).round(2)

print(df_desired_output)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:38:30