4. 总账与明细账数据一致性核对
任务说明
本案例实现总账与明细账的一致性核对:读取总账(科目、期间、期初余额、期末余额)与明细账(科目、期间、借方发生额、贷方发生额),按“科目+期间”汇总明细账发生额,计算明细账推算的期末余额(期初余额 + 借方 - 贷方),再与总账期末余额比对,标记差异科目。
环境与依赖
- Python 3.8+,依赖 pandas:
pip install pandas - 输入为两个 CSV 文件:
general_ledger.csv、detail_ledger.csv
输入数据示例
总账 general_ledger.csv:
科目,期间,期初余额,期末余额
1001,2024-01,10000,12000
1002,2024-01,5000,4500
1001,2024-02,12000,15000
明细账 detail_ledger.csv:
科目,期间,借方发生额,贷方发生额
1001,2024-01,3000,1000
1002,2024-01,500,1000
1001,2024-02,4000,1000
核对逻辑
完整代码
import pandas as pd
def reconcile(gl_path, dl_path, tol=0.01):
gl = pd.read_csv(gl_path, dtype={"科目": str})
dl = pd.read_csv(dl_path, dtype={"科目": str})
# 按科目+期间汇总明细账发生额
agg = dl.groupby(["科目", "期间"], as_index=False).agg(
借方发生额=("借方发生额", "sum"),
贷方发生额=("贷方发生额", "sum"),
)
# 合并总账与明细账汇总
merged = gl.merge(agg, on=["科目", "期间"], how="outer")
# 明细账推算期末余额 = 期初余额 + 借方 - 贷方
merged["推算期末余额"] = (
merged["期初余额"].fillna(0)
+ merged["借方发生额"].fillna(0)
- merged["贷方发生额"].fillna(0)
)
# 差异 = 总账期末余额 - 推算期末余额
merged["差异"] = merged["期末余额"].fillna(0) - merged["推算期末余额"]
merged["是否一致"] = merged["差异"].abs() <= tol
diff = merged[~merged["是否一致"]].copy()
return merged, diff
if __name__ == "__main__":
merged, diff = reconcile("general_ledger.csv", "detail_ledger.csv")
print("=== 全部核对结果 ===")
print(merged[["科目", "期间", "期末余额", "推算期末余额", "差异", "是否一致"]])
print("\n=== 差异科目 ===")
if diff.empty:
print("无差异,全部一致")
else:
print(diff[["科目", "期间", "期末余额", "推算期末余额", "差异"]])
运行与验证
- 将上述两个 CSV 与脚本放在同一目录,执行
python reconcile.py。 - 观察输出:
是否一致为 True 表示该科目该期间总账与明细账一致;为 False 的行即差异科目。 - 以上述示例数据为例,1002 科目 2024-01 推算期末余额为 5000+500-1000=4500,与总账 4500 一致;若将明细账 1002 借方改为 600,则推算为 4600,与总账 4500 差异 -100,会被标记为差异科目。
- 通过条件:差异科目列表与人工核对结果一致,且一致科目差异绝对值不超过容差
tol。