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

如何基于含value、count列的分组DataFrame计算等效统计量

分组DataFrame的统计量计算(匹配未分组数据的describe结果)

假设你有一个包含value(数值)和count(出现次数)的DataFrame,要计算与未分组数据调用df.describe()一致的最小值、最大值、中位数及百分位数,可按以下步骤实现:

核心思路

未分组数据的统计量基于每个个体值计算,分组数据需通过累积计数定位统计量位置,并对跨分组的情况做线性插值(匹配pandas默认的分位数计算逻辑)。

具体实现步骤

1. 预处理:排序并计算累积计数

先对value列排序,确保数值按从小到大排列,再计算累积出现次数,用于定位统计量的位置:

import pandas as pd

# 示例DataFrame
df = pd.DataFrame({'value': [2, 5, 3, 7], 'count': [1000, 500, 800, 200]})
# 按value排序
df_sorted = df.sort_values('value').reset_index(drop=True)
# 计算累积计数
df_sorted['cum_count'] = df_sorted['count'].cumsum()
# 总样本数
total_samples = df_sorted['cum_count'].iloc[-1]

2. 计算最小值和最大值

直接取排序后value列的首尾值即可:

min_value = df_sorted['value'].iloc[0]
max_value = df_sorted['value'].iloc[-1]

3. 计算中位数和百分位数

pandas默认使用线性插值法计算分位数,手动实现该逻辑以匹配describe()结果:

def weighted_percentile(df_sorted, percentile):
    # 计算分位数对应的位置
    pos = total_samples * (percentile / 100)
    
    # 边界情况处理
    if pos <= 1:
        return df_sorted['value'].iloc[0]
    if pos >= total_samples:
        return df_sorted['value'].iloc[-1]
    
    # 找到相邻的两个分组
    lower_row = df_sorted[df_sorted['cum_count'] < pos].iloc[-1]
    upper_row = df_sorted[df_sorted['cum_count'] >= pos].iloc[0]
    
    # 线性插值计算分位数
    lower_cum = lower_row['cum_count']
    upper_cum = upper_row['cum_count']
    lower_val = lower_row['value']
    upper_val = upper_row['value']
    
    fraction = (pos - lower_cum) / (upper_cum - lower_cum)
    return lower_val + fraction * (upper_val - lower_val)

# 计算常用统计量
median = weighted_percentile(df_sorted, 50)
q25 = weighted_percentile(df_sorted, 25)  # 25%分位数
q75 = weighted_percentile(df_sorted, 75)  # 75%分位数

4. 整合结果(模拟describe输出)

把结果整理成类似describe()的格式:

# 计算均值和标准差
mean_val = (df_sorted['value'] * df_sorted['count']).sum() / total_samples
var_val = (((df_sorted['value'] - mean_val)**2) * df_sorted['count']).sum() / total_samples
std_val = var_val ** 0.5

stats = pd.Series({
    'count': total_samples,
    'mean': mean_val,
    'std': std_val,
    'min': min_value,
    '25%': q25,
    '50%': median,
    '75%': q75,
    'max': max_value
})

print(stats)

验证一致性

可以将分组数据展开为未分组数据,调用describe()对比结果:

# 展开成未分组数据
unpacked_df = df_sorted.loc[df_sorted.index.repeat(df_sorted['count'])][['value']]
# 对比输出
print(unpacked_df.describe())
print(stats)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:45:25