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

Pandas DataFrame交叉表按行计算元素占比概率的实现问题

问题解决

错误原因说明

  • 你写的prob = [i/sum(i) for i in range(df)]报错是因为range()只能接收整数参数,不能直接传入DataFrame对象,逻辑本身也不符合需求。
  • 后续apply写法结果不准是两个原因导致:第一apply默认axis=0按列计算,你需要的是按行维度计算需要指定axis=1;第二你用iloc[:, 1:]切掉了第一列数据,结果自然不符合预期。

方案1:直接用pd.crosstab自带参数实现(最简便)

pd.crosstab本身自带归一化参数,指定normalize='index'即可直接按行维度计算概率,无需后续二次处理:

import pandas as pd
data = pd.DataFrame({'id_' : [1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010],
        'A' : [1608, 1608, 2089, 213, 1005, 1887, 2089, 4544, 6866, 2020, 2020],
                   'B' : [1772, 1772, 1608, 1608, 1790, 1790, 1791, 1791, 1772, 1799, 1799],
                        'C': [1772,1608, 1005,1791, 4544, 2020, 1791, 1772, 1799, 2020, 213],
                       })
# normalize='index'表示按行求和做归一化,round(2)保留两位小数得到0.33的效果
prob_df = pd.crosstab(data['B'], data['C'], normalize='index').round(2)
print(prob_df)

方案2:对已有crosstab计数结果做行归一化

如果你已经生成了原始的计数df,调整apply的参数即可:

df = pd.crosstab(data['B'], data['C'])
# axis=1指定逐行计算,每行元素除以该行的总和
prob_df = df.apply(lambda x: x/x.sum(), axis=1).round(2)
print(prob_df)

方案3:不用crosstab的替代实现

用groupby+value_counts也可以实现需求:

# 按B分组,统计每组内C的取值占比,再unstack转成宽表格式
prob_df = data.groupby('B')['C'].value_counts(normalize=True).unstack(fill_value=0).round(2)
print(prob_df)

三种方案运行后输出的结果都和你给出的预期结果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:36:05