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

Python/Pandas合并月度薪资报表并生成差异列及差异报告需求

解决方案:薪资文件对比与差异自动化处理

1. 预处理:统一列名,解决月度列头不一致问题

先处理月度报表列名大小写、空格、位置不一致的问题,通过标准化列名确保合并匹配准确:

import pandas as pd
from openpyxl import load_workbook

# 列名标准化函数:统一转小写、替换空格为下划线
def standardize_columns(df):
    df.columns = df.columns.str.lower().str.replace(' ', '_')
    return df

# 读取并标准化两份薪资报表
dfnew = standardize_columns(pd.read_csv("sep22.csv"))
dfold = standardize_columns(pd.read_csv("Aug22.csv"))

# 以标准化后的员工编码为键合并,保留当月所有员工数据
mergedfiles = pd.merge(dfnew, dfold, on='employee_code', how='left')

# 设置员工编码为索引,按列名排序方便查看(可选)
mergedfiles = mergedfiles.set_index('employee_code').sort_index(axis=1)

2. 自动生成差异列(硬编码数值/Excel公式二选一)

选项A:硬编码差异数值(直接计算结果)

遍历所有配对列,自动生成_diff列并插入到对应_x/_y列之后:

# 获取所有配对列的原始名称(去除_x/_y后缀)
original_cols = list(set(col.split('_')[0] for col in mergedfiles.columns if '_' in col))

for col in original_cols:
    # 检查当月和上月列是否同时存在
    if f"{col}_x" in mergedfiles.columns and f"{col}_y" in mergedfiles.columns:
        # 计算差异:当月值 - 上月值
        mergedfiles[f"{col}_diff"] = mergedfiles[f"{col}_x"] - mergedfiles[f"{col}_y"]
        # 将差异列插入到_y列的下一个位置
        col_index = mergedfiles.columns.get_loc(f"{col}_y") + 1
        mergedfiles = mergedfiles.reindex(
            columns=list(mergedfiles.columns[:col_index]) + [f"{col}_diff"] + list(mergedfiles.columns[col_index:-1])
        )

# 保存含差异列的文件
mergedfiles.to_excel("new_v_old_with_diff.xlsx")

选项B:插入Excel公式(保留动态计算能力)

使用openpyxl引擎写入Excel公式,后续修改原始值时差异会自动更新:

# 先保存基础合并文件
mergedfiles.to_excel("new_v_old_with_formula.xlsx", engine='openpyxl')

# 加载工作簿并写入公式
wb = load_workbook("new_v_old_with_formula.xlsx")
ws = wb.active

# 建立列名与Excel列号的映射(如A、B、C...)
col_map = {cell.value: chr(65 + idx) for idx, cell in enumerate(ws[1])}

for col in original_cols:
    if f"{col}_x" in mergedfiles.columns and f"{col}_y" in mergedfiles.columns:
        # 获取_x和_y列对应的Excel列字母
        x_col = col_map[f"{col}_x"]
        y_col = col_map[f"{col}_y"]
        # 计算差异列的位置(在_y列之后)
        diff_col_idx = list(col_map.values()).index(y_col) + 1
        diff_col_letter = chr(65 + diff_col_idx)
        
        # 写入差异列标题
        ws[f"{diff_col_letter}1"] = f"{col}_diff"
        
        # 逐行写入差异公式
        for row in range(2, ws.max_row + 1):
            ws[f"{diff_col_letter}{row}"] = f"={x_col}{row}-{y_col}{row}"

# 保存带公式的文件
wb.save("new_v_old_with_formula.xlsx")

3. 生成仅含差异数据的报告

筛选出有差异的记录,按薪资项分组整理成指定格式:

# 生成差异标记矩阵:标记差异不为0且非空的单元格
diff_mask = mergedfiles.filter(like='_diff').ne(0) & mergedfiles.filter(like='_diff').notna()

# 整理差异报告内容
report_content = []
for col in original_cols:
    diff_col = f"{col}_diff"
    if diff_col in diff_mask.columns:
        # 获取该薪资项有差异的员工
        diff_emp_ids = diff_mask[diff_col][diff_mask[diff_col]].index
        if len(diff_emp_ids) > 0:
            # 转换回中文列名格式(如salary -> 薪资)
            item_name = col.replace('_', ' ')
            report_content.append(f"> {item_name}:")
            for emp_id in diff_emp_ids:
                x_val = mergedfiles.loc[emp_id, f"{col}_x"]
                y_val = mergedfiles.loc[emp_id, f"{col}_y"]
                diff_val = mergedfiles.loc[emp_id, diff_col]
                # 获取员工姓氏(假设列名为last_name,可根据实际调整)
                last_name = mergedfiles.loc[emp_id, 'last_name']
                report_content.append(f"> {last_name} {x_val}; {y_val}; {diff_val}")
            report_content.append("> ")

# 在Jupyter中输出报告
print('\n'.join(report_content))

# 保存报告到文本文件
with open("payroll_diff_report.txt", 'w') as f:
    f.write('\n'.join(report_content))

关键说明

  • 列名标准化:通过统一格式消除月度报表列名的格式差异,避免合并时匹配错误。
  • 差异列排版:自动将差异列插入对应_x/_y列之后,保持数据逻辑连贯。
  • 差异报告:仅提取有变化的薪资项和员工,减少冗余信息,提升审核效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:55:19