4. Python数据处理基础
在精算现金流模型中,数据质量直接决定模型输出的可信度。pandas 是 Python 生态中处理结构化数据的核心工具,它提供了两种基础数据结构:Series(带标签的一维数组)和 DataFrame(带行列标签的二维表格)。精算工作中的保单表、缴费计划、赔付记录、利率曲线,几乎都可以映射为 DataFrame 的行与列。理解这两种结构,是后续所有清洗、索引与转换操作的前提。
核心原理:索引对齐与标签语义
pandas 与 NumPy 最大的区别在于标签索引。DataFrame 的每一行有 index,每一列有 columns,运算时 pandas 会按标签自动对齐,而不是按位置。这一特性在精算场景中非常关键:当把死亡率表、退保率表与保单主表合并时,若索引语义不一致,就会产生大量 NaN 或错位结果。因此,建模前必须先明确“索引代表什么”——是保单号、时间点,还是产品代码。
方法流程:从原始表到可用现金流表
一个标准的精算数据处理流程通常包含以下步骤:
- 载入:使用
pd.read_csv()或pd.read_excel()读取数据,注意指定dtype和parse_dates参数,避免数值被误读为字符串。 - 探查:通过
df.info()、df.describe()、df.isna().sum()快速了解字段类型、分布与缺失情况。 - 清洗:统一列名、去除重复行、修正异常值、转换数据类型。
- 缺失值处理:根据业务含义选择删除、填充或插值。
- 时间索引:将期间字段转换为
DatetimeIndex,支持按年、季、月重采样。 - 转换与输出:透视、合并、分组聚合后写出为 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 的数据结构与清洗方法后,精算工程师就能把杂乱的原始数据转化为结构清晰、索引对齐、可直接参与逐期计算的现金流表。这是后续构建贴现模型、准备金评估与情景测试的工程基础。