Pandas聚合DataFrame时如何避免自动丢弃<NA>空分组行?
原因分析
你设置的observed=False参数仅对Categorical(分类)类型的分组列生效,你当前参与分组的4列大概率是object字符串类型,因此该参数无法触发保留全量维度组合的逻辑,空分组自然会被自动删除。
解决方法
有两种可直接落地的实现方案,按需选择即可:
方案1:将分组列转为分类类型(简单快捷)
先把所有参与分组的列转为Pandas分类类型,再执行groupby即可:
import pandas as pd # 第一步:先按规则生成Shelf Life列 expire_map = { '30 Days': 'Monthly', '60 Days': 'Seasonal', '90 Days': 'Seasonal', '15 Days': 'Monthly' } df['Shelf Life'] = df['Expiration'].map(expire_map) groupby_list = ['Item Category', 'Shelf Life', 'Product Type', 'Brand Type'] # 第二步:将所有分组列转为分类类型 for col in groupby_list: # 如果有未出现在当前数据里的维度取值,可手动指定categories参数,比如: # df[col] = pd.Categorical(df[col], categories=['取值1', '取值2', '取值3']) df[col] = pd.Categorical(df[col]) # 第三步:执行聚合,自动保留全量组合 grouped_df = df.groupby( by=groupby_list, observed=False, dropna=False )[['Purchases', 'Cost','Sales']].sum().fillna(0)
方案2:手动生成全量维度组合(灵活可控)
如果需要自定义维度取值(比如要包含从未在数据里出现过的分类),可以手动生成笛卡尔积维度表后关联聚合结果:
import pandas as pd # 先执行常规聚合得到有数据的分组结果 groupby_list = ['Item Category', 'Shelf Life', 'Product Type', 'Brand Type'] temp_group = df.groupby(by=groupby_list)[['Purchases', 'Cost','Sales']].sum() # 定义每个维度的所有可能取值,也可以手动写固定列表 dim_values = [ df['Item Category'].unique(), ['Monthly', 'Seasonal'], # 直接固定保质期分类避免脏数据 df['Product Type'].unique(), df['Brand Type'].unique() ] # 生成所有维度的全量组合索引 full_index = pd.MultiIndex.from_product(dim_values, names=groupby_list) # 重索引补全缺失分组,空值填0 grouped_df = temp_group.reindex(full_index, fill_value=0)
两种方案输出的结果都和你预期的Ex.2格式完全一致,缺失的分组会自动补0保留。
内容的提问来源于stack exchange,提问作者user16537374
相关产品推荐
相关产品推荐

