4. Python数据处理基础

在精算现金流模型中,数据质量直接决定模型输出的可信度。pandas 是 Python 生态中处理结构化数据的核心工具,它提供了两种基础数据结构:Series(带标签的一维数组)和 DataFrame(带行列标签的二维表格)。精算工作中的保单表、缴费计划、赔付记录、利率曲线,几乎都可以映射为 DataFrame 的行与列。理解这两种结构,是后续所有清洗、索引与转换操作的前提。

核心原理:索引对齐与标签语义

pandas 与 NumPy 最大的区别在于标签索引。DataFrame 的每一行有 index,每一列有 columns,运算时 pandas 会按标签自动对齐,而不是按位置。这一特性在精算场景中非常关键:当把死亡率表、退保率表与保单主表合并时,若索引语义不一致,就会产生大量 NaN 或错位结果。因此,建模前必须先明确“索引代表什么”——是保单号、时间点,还是产品代码。

现金流表数据处理管线 原始数据源 CSV / Excel / DB read_csv / read_excel DataFrame 载入 数据清洗 类型 / 去重 / 缺失值 时间序列索引 DatetimeIndex 现金流表:期间 / 保费 / 赔付 / 退保 / 利率 to_csv / to_excel 输出 缺失值处理 fillna / dropna / 插值 输出:对齐后的现金流矩阵,供精算模型逐期计算使用

方法流程:从原始表到可用现金流表

一个标准的精算数据处理流程通常包含以下步骤:

  1. 载入:使用 pd.read_csv() 或 pd.read_excel() 读取数据,注意指定 dtype 和 parse_dates 参数,避免数值被误读为字符串。
  2. 探查:通过 df.info()、df.describe()、df.isna().sum() 快速了解字段类型、分布与缺失情况。
  3. 清洗:统一列名、去除重复行、修正异常值、转换数据类型。
  4. 缺失值处理:根据业务含义选择删除、填充或插值。
  5. 时间索引:将期间字段转换为 DatetimeIndex,支持按年、季、月重采样。
  6. 转换与输出:透视、合并、分组聚合后写出为 CSV 或 Excel。
import pandas as pd

# 载入现金流表,指定日期列与数值类型
df = pd.read_csv(
    "cashflow_raw.csv",
    parse_dates=["period"],
    dtype={"policy_id": "string", "premium": "float64"}
)

# 探查缺失与类型
print(df.info())
print(df.isna().sum())

# 清洗:去重、统一列名
df = df.drop_duplicates(subset=["policy_id", "period"])
df.columns = [c.strip().lower() for c in df.columns]

# 缺失值:保费缺失按 0 处理,利率缺失前向填充
df["premium"] = df["premium"].fillna(0.0)
df["interest_rate"] = df["interest_rate"].ffill()

# 时间序列索引
df = df.set_index("period").sort_index()

# 按月重采样,汇总保费与赔付
monthly = df.resample("M").agg({"premium": "sum", "claim": "sum"})
monthly.to_csv("cashflow_monthly.csv")

案例场景:保单现金流表的清洗与对齐

假设我们有一张保单现金流表,包含 policy_id、period、premium、claim、interest_rate 五个字段。实际数据中常见三类问题:一是 period 为字符串格式,无法直接做时间运算;二是部分保单的 interest_rate 缺失;三是同一保单同一期间存在重复记录。处理策略如下表所示:

问题类型 检测方法 处理策略 pandas 方法
日期为字符串 df.dtypes 转换为 datetime pd.to_datetime()
重复记录 df.duplicated() 按业务主键去重 drop_duplicates()
利率缺失 df.isna().sum() 前向填充或按产品均值填充 ffill() / fillna()
保费缺失 df["premium"].isna() 按业务规则补 0 或剔除 fillna(0) / dropna()
索引非时间 df.index.dtype 设为 DatetimeIndex set_index()
提示:在精算模型中,缺失值处理不能只看统计指标,必须结合业务含义。例如利率缺失若用 0 填充,会严重低估贴现因子;而保费缺失用 0 填充,通常符合“未缴费即无现金流”的业务逻辑。

误区与复盘

初学者在 pandas 处理现金流表时,最容易踩以下三个坑:

  • 链式赋值警告:使用 df[df["x"]>0]["y"] = 1 会触发 SettingWithCopyWarning,应改用 .loc 或先 .copy()。
  • 索引未排序:时间序列重采样前必须 sort_index(),否则 resample() 结果可能错乱。
  • 隐式类型转换:读取 CSV 时若未指定 dtype,保单号可能被解析为整数,丢失前导零,导致后续合并失败。
警告:现金流表的读写与转换必须保留可追溯性。建议在清洗前后分别保存快照,并记录每一步的行数变化,便于模型审计与复现。

掌握 pandas 的数据结构与清洗方法后,精算工程师就能把杂乱的原始数据转化为结构清晰、索引对齐、可直接参与逐期计算的现金流表。这是后续构建贴现模型、准备金评估与情景测试的工程基础。