为何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
相关产品推荐
相关产品推荐

