如何在Pandas按星期分组后添加仅单列求和的总计行(去除NaN)
Pandas按星期分组统计后,修复总计行分类列显示NaN的问题
场景与现有代码
需求是将数据按星期几分组统计记录数量,并添加总计行,但当前总计行的inc_Day_of_Week列显示NaN,需要改为显示“Total”。现有代码如下:
import pandas as pd df = { 'inc_date':['06-Jul-2020','06-Jul-2020','06-Jul-2020','07-Jul-2020','08-Jul-2020','08-Jul-2020','09-Jul-2020',], } df = pd.DataFrame(dict(df)) df['inc_Day_of_Week'] = pd.DatetimeIndex(df['inc_date']).day_name() # 生成星期几列 print(df) dfTemp = df.groupby(['inc_Day_of_Week']).size() dfTemp = dfTemp.reset_index(name='inc_volume').sort_index() # 设置星期顺序为周一到周日 cats = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] dfTemp['inc_Day_of_Week'] = pd.Categorical(dfTemp['inc_Day_of_Week'], categories=cats, ordered=True) dfTemp.loc['Total'] = dfTemp.sum(numeric_only=True) display(dfTemp)
当前输出问题
运行后总计行的inc_Day_of_Week列显示NaN:
inc_Day_of_Week inc_volume 0 Monday 3.0 1 Thursday 1.0 2 Tuesday 1.0 3 Wednesday 2.0 Total NaN 7.0
期望总计行显示:
Total 7.0
用户尝试的失败代码
曾尝试用append添加总计行,但未解决问题:
dfTotal1 = [[dfTemp.inc_volume.sum()]] dfTotal2 = pd.DataFrame(dfTotal1,columns=['inc_volume']) dfTemp.append(dfTotal2)
解决方案
方法1:修改总计行的分类列值(简单直接)
因为原列是分类类型,需要先将“Total”纳入分类范围,或者临时转换为字符串类型后赋值:
# 方案1:扩展分类列表,提前包含Total cats = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Total'] dfTemp['inc_Day_of_Week'] = pd.Categorical(dfTemp['inc_Day_of_Week'], categories=cats, ordered=True) # 添加总计行 dfTemp.loc['Total'] = dfTemp.sum(numeric_only=True) # 给总计行的分类列赋值 dfTemp.loc['Total', 'inc_Day_of_Week'] = 'Total'
或临时转为字符串类型再赋值(适合不需要保持分类排序的场景):
# 方案2:转字符串类型后修改 dfTemp['inc_Day_of_Week'] = dfTemp['inc_Day_of_Week'].astype(str) dfTemp.loc['Total'] = dfTemp.sum(numeric_only=True) dfTemp.loc['Total', 'inc_Day_of_Week'] = 'Total'
方法2:构造总计行后合并(更规范)
单独构造总计行DataFrame,再与原数据合并,同时处理分类类型:
# 构造总计行 total_row = pd.DataFrame({ 'inc_Day_of_Week': ['Total'], 'inc_volume': [dfTemp['inc_volume'].sum()] }) # 合并原数据和总计行 dfTemp = pd.concat([dfTemp, total_row], ignore_index=False) # 重新设置包含Total的分类列表并排序 cats_with_total = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Total'] dfTemp['inc_Day_of_Week'] = pd.Categorical(dfTemp['inc_Day_of_Week'], categories=cats_with_total, ordered=True) dfTemp = dfTemp.sort_values('inc_Day_of_Week')
失败原因说明
append方法在Pandas 2.0及以上版本已被弃用,官方推荐使用pd.concat- 之前的代码未给总计行设置
inc_Day_of_Week值,导致该列显示NaN - 原列是分类类型,新行的“Total”不在原有分类列表中,会被标记为NaN,需要先扩展分类或转换类型
内容的提问来源于stack exchange,提问作者Peter Lucas
相关产品推荐
相关产品推荐

