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

Python中如何基于离散数据计算累积分布函数并查询分位值

离散概率分布、累积分布计算及分位值查询实现

不需要依赖小众第三方工具包,基于pandas、scipy即可快速实现需求。

基础准备:计算累积分布(CDF)

首先对结果值排序后,累加概率列即可得到累积分布:

import pandas as pd

# 示例数据
data = {'Result': [1, 2, 4, 6],
        'Occurrence': [2,3,4,1],
        'Probability':[0.2,0.3,0.4,0.1]}
df= pd.DataFrame(data)

# 必须先按结果值升序排序,否则累积计算结果错误
df = df.sort_values('Result').reset_index(drop=True)
# 计算累积概率
df['CDF'] = df['Probability'].cumsum()

计算完成后得到的分布表如下:

ResultOccurrenceProbabilityCDF
120.20.2
230.30.5
440.40.9
610.11.0

其中Probability列是离散概率分布(PMF)值,CDF列是累积分布值,对应横轴为Result、纵轴为概率的绘图需求。

分位值查询:获取指定概率水平对应的结果值

离散分布的分位值规则为:找到最小的结果值x,使得x对应的累积概率大于等于目标概率水平,两种常用实现方式如下:

方式1:纯pandas实现(无额外依赖)

用pandas内置的merge_asof做近似匹配,不需要手动写循环,可批量查询多个概率水平:

def get_discrete_quantile(input_df, target_prob_list):
    """
    批量查询离散分布指定概率对应的结果值
    参数:
        - input_df: 包含Result、Probability列的原始分布DataFrame
        - target_prob_list: 目标概率水平列表,如[0.5, 0.6, 0.8]
    """
    # 临时表计算CDF,避免修改原数据
    temp = input_df.sort_values('Result').reset_index(drop=True)
    temp['CDF'] = temp['Probability'].cumsum()
    # 构造查询表
    query = pd.DataFrame({'target_prob': target_prob_list})
    # 向前匹配:找到第一个CDF大于等于目标概率的行
    res = pd.merge_asof(
        query,
        temp[['CDF', 'Result']],
        left_on='target_prob',
        right_on='CDF',
        direction='forward'
    )
    return res

# 调用示例
targets = [0.5, 0.6, 0.8]
quantile_res = get_discrete_quantile(df, targets)
print(quantile_res)

输出结果:

target_prob  CDF  Result
0          0.5  0.5       2
1          0.6  0.9       4
2          0.8  0.9       4

结果说明:

  • 50%概率对应结果2,累积到结果2时概率刚好达到0.5
  • 60%、80%概率对应结果4,因为结果2的累积概率仅为0.5,下一个结果4的累积概率达到0.9,覆盖0.5~0.9区间的所有概率水平

方式2:scipy统计接口实现

如果习惯使用标准统计库接口,可使用scipy.stats.rv_discrete构造离散分布对象,直接调用ppf(分位函数)查询:

from scipy import stats

# 构造离散分布实例
dist = stats.rv_discrete(values=(df['Result'], df['Probability']))
# 直接传入目标概率列表查询
print(dist.ppf([0.5, 0.6, 0.8]))
# 输出: [2. 4. 4.],和纯pandas实现结果完全一致

可选:分布可视化

用matplotlib可快速绘制双轴图同时展示概率分布和累积分布:

import matplotlib.pyplot as plt

fig, ax1 = plt.subplots(figsize=(8,4))
# 绘制概率分布柱状图
ax1.bar(df['Result'], df['Probability'], color='#1f77b4', alpha=0.6, label='PMF 概率分布')
ax1.set_xlabel('Result 结果值')
ax1.set_ylabel('Probability 概率', color='#1f77b4')

# 绘制累积分布阶梯图
ax2 = ax1.twinx()
ax2.step(df['Result'], df['CDF'], color='#ff7f0e', where='post', linewidth=2, label='CDF 累积分布')
ax2.set_ylabel('Cumulative Probability 累积概率', color='#ff7f0e')
ax2.set_ylim(0, 1.05)

fig.legend(loc='upper center', ncol=2)
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 09:18:27