Pandas如何批量将指定行年度汇总列设为该行最后一个非零季度值
Pandas 批量计算多团队绩效年度汇总解决方案
错误原因
你之前的写法是直接对整个Series使用if判断,Pandas无法直接对序列整体返回单个布尔值,因此会抛出ValueError: The truth value of a Series is ambiguous错误,该写法仅支持单元素判断,不适合批量多行处理。
核心实现逻辑
针对两类KPI的计算需求,用向量化操作实现批量处理,无需逐行判断:
- 销售类KPI:直接按行对季度列求和
- 信息类KPI:将0替换为空值后按行向前填充,取最后一列的值即为最后一个非零季度值
可复用代码实现
1. 单年度单行批量处理
import pandas as pd # 示例输入df df = pd.DataFrame({ '2020_Q1': [2, 3, 6, 20, 20], '2020_Q2': [2, 3, 6, 20, 20], '2020_Q3': [5, 3, 6, 20, 20], '2020_Q4': [5, 4, 6, 20, 20], '2021_Q1': [5, 3, 7, 20, 20], '2021_Q2': [5, 4, 7, 20, 20], '2021_Q3': [5, 4, 0, 20, 20], }, index = ['People', 'AA', 'BB', 'MM', '$$']) # 配置参数 info_rows = ['People', 'AA', 'BB'] # 需取最后非零值的信息类KPI行 sum_rows = ['MM', '$$'] # 需求和的销售类KPI行 # 批量处理2020年度汇总 year = '2020' q_cols = [c for c in df.columns if c.startswith(year)] # 信息类行单行赋值 df.loc[info_rows, f'{year}_Total'] = df.loc[info_rows, q_cols].replace(0, pd.NA).ffill(axis=1).iloc[:, -1] # 求和类行赋值 df.loc[sum_rows, f'{year}_Total'] = df.loc[sum_rows, q_cols].sum(axis=1) # 批量处理2021年度汇总 year = '2021' q_cols = [c for c in df.columns if c.startswith(year)] df.loc[info_rows, f'{year}_Total'] = df.loc[info_rows, q_cols].replace(0, pd.NA).ffill(axis=1).iloc[:, -1] df.loc[sum_rows, f'{year}_Total'] = df.loc[sum_rows, q_cols].sum(axis=1)
2. 全年度循环批量处理
如果需要处理多个年度,直接套循环即可:
# 提取所有需要处理的年度 years = list(set([c.split('_')[0] for c in df.columns if '_Q' in c])) for year in years: q_cols = [c for c in df.columns if c.startswith(year)] df.loc[info_rows, f'{year}_Total'] = df.loc[info_rows, q_cols].replace(0, pd.NA).ffill(axis=1).iloc[:, -1] df.loc[sum_rows, f'{year}_Total'] = df.loc[sum_rows, q_cols].sum(axis=1)
输出结果验证
最终输出结果完全符合预期:
2020_Q1 2020_Q2 2020_Q3 2020_Q4 2021_Q1 2021_Q2 2021_Q3 2020_Total 2021_Total People 2 2 5 5 5 5 5 5.0 5.0 AA 3 3 3 4 3 4 4 4.0 4.0 BB 6 6 6 6 7 7 0 6.0 7.0 MM 20 20 20 20 20 20 20 80.0 60.0 $$ 20 20 20 20 20 20 20 80.0 60.0
内容的提问来源于stack exchange,提问作者GiveGet_15
相关产品推荐
相关产品推荐

