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

为何pandas cut会影响groupby分组结果的行数?

Pandas groupby 结果行数差异原因解析

版本1:直接赋值分组键

import pandas as pd

data = {
    'col1': [4],
    'col2': [1],
    'col3': ['gg'],
    'uplift_ratio': [0.94],
    'p1': [1],
    'p2': [103],
}
df = pd.DataFrame(data)
df['bucket_int'] = 2
print(df.groupby(by=['col1', 'col2', 'col3'] + ['bucket_int']).agg({'p2': sum}).reset_index())

输出(仅1行):

col1  col2 col3  bucket_int   p2
0     4     1   gg           2  103

版本2:使用pd.cut生成分组键

import pandas as pd

data = {
    'col1': [4],
    'col2': [1],
    'col3': ['gg'],
    'uplift_ratio': [0.94],
    'p1': [1],
    'p2': [103],
}
df2 = pd.DataFrame(data)

data_config={'uplift_buckets': [0.8, 0.85, 0.9, 0.95, 1.0]}
df2['bucket'] = pd.cut(df2['uplift_ratio'], bins=data_config['uplift_buckets'])
df2['bucket_int'] = pd.cut(
    df2['uplift_ratio'], bins=data_config['uplift_buckets'],
    labels=list(range(len(data_config['uplift_buckets']) - 1))
)

df2.groupby(by=['col1', 'col2', 'col3'] + ['bucket_int']).agg({'p2': sum}).reset_index()

注:原代码中groupby列名笔误已修正
输出(共4行):

col1  col2 col3 bucket_int      p2
0     4     1   gg          0    0.000
1     4     1   gg          1    0.000
2     4     1   gg          2  103.000
3     4     1   gg          3    0.000

原因解析

核心差异在于bucket_int的数据类型:

  • 版本1中,df['bucket_int'] = 2生成的是普通int64类型列,groupby只会根据数据中实际存在的键值(这里只有2)分组聚合,因此结果仅1行。
  • 版本2中,pd.cut指定labels参数后,生成的bucket_int是Categorical(分类)类型。该类型会预先定义所有可能的类别(此处为[0,1,2,3]四个值),哪怕数据中只存在2这个类别,groupby时仍会遍历所有预设类别;对于无对应数据的类别,sum聚合结果会填充为0,最终输出4行。

如果想让版本2的groupby只保留有数据的类别,可添加observed=True参数:

df2.groupby(by=['col1', 'col2', 'col3'] + ['bucket_int'], observed=True).agg({'p2': sum}).reset_index()

修改后输出将和版本1一致,仅保留1行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:32:02