2. 数据源获取与初步认识:使用Python读取催收系统导出的CSV/Excel文件

在催收异常复盘项目中,第一步是获取原始数据并建立对其结构、类型与质量的初步认知。催收系统通常支持导出为 CSV 或 Excel 格式,字段包含但不限于:手机号、触达时间、状态码、客户姓名、案件编号等。本节将演示如何使用 Python 的 pandas 库读取这些文件,并展示原始数据的全貌。

2.1 数据源文件结构预览

典型的催收触达记录导出文件包含以下核心字段,下表列出了常见字段及其业务含义:

字段名 数据类型 业务含义 示例值
case_id 字符串 案件唯一编号 CS20241001-001
customer_name 字符串 客户姓名 张三
phone_number 字符串 客户手机号 138****1234
contact_time 日期时间 催收触达时间 2024-10-01 09:15:30
status_code 整数 触达结果状态码 200
duration_sec 整数 通话时长(秒) 120
agent_id 字符串 催收员编号 AG-0451

2.2 使用Pandas读取CSV文件

Python 的 pandas 库提供了 read_csv() 函数,可以快速将 CSV 文件加载为 DataFrame。以下代码演示了基本读取操作,并展示前 5 行数据:

import pandas as pd

# 读取催收系统导出的CSV文件
file_path = "data/collection_contact_20241001.csv"
df = pd.read_csv(file_path, encoding='utf-8')

# 展示数据基本信息
print("数据形状(行数, 列数):", df.shape)
print("\n前5行数据预览:")
print(df.head())

# 查看各列数据类型
print("\n各列数据类型:")
print(df.dtypes)

输出示例:

数据形状(行数, 列数): (15000, 8)

前5行数据预览:
   case_id customer_name   phone_number        contact_time  status_code  duration_sec agent_id
0  CS20241001-001         张三  13800138001  2024-10-01 09:15:30          200           120  AG-0451
1  CS20241001-002         李四  13900139002  2024-10-01 09:18:45          404             0  AG-0451
2  CS20241001-003         王五  13700137003  2024-10-01 09:22:10          500             0  AG-0452
3  CS20241001-004         赵六  13600136004  2024-10-01 09:30:00          200            85  AG-0453
4  CS20241001-005         孙七  13500135005  2024-10-01 09:35:20          200           200  AG-0451

各列数据类型:
case_id          object
customer_name    object
phone_number     object
contact_time     object
status_code      int64
duration_sec     int64
agent_id         object
dtype: object
💡 提示: 注意 contact_time 列被识别为 object(字符串)类型,而非 datetime。在后续数据清洗中,需要将其转换为标准时间格式,以便进行时间维度的异常分析。

2.3 读取Excel文件的差异

如果催收系统导出的是 .xlsx 格式,需要使用 read_excel() 函数,并可能需要指定工作表名称:

# 读取Excel文件
df_excel = pd.read_excel("data/collection_contact_20241001.xlsx", sheet_name=0)

# 快速查看数据摘要
print("Excel数据摘要:")
print(df_excel.info())

两种读取方式返回的 DataFrame 结构一致,但 read_excel() 对日期格式的自动推断能力更强,部分情况下可直接识别为 datetime64 类型。

2.4 原始数据初步认识:字段质量扫描

在正式清洗前,需要对原始数据进行快速质量扫描,重点关注缺失值、重复记录和异常状态码。以下代码展示了基础扫描方法:

# 缺失值统计
print("各列缺失值数量:")
print(df.isnull().sum())

# 重复行检查
print("\n完全重复行数:", df.duplicated().sum())

# 状态码分布统计
print("\n状态码分布:")
print(df['status_code'].value_counts().sort_index())

输出示例:

各列缺失值数量:
case_id          0
customer_name    0
phone_number     0
contact_time     0
status_code      0
duration_sec     0
agent_id         0
dtype: int64

完全重复行数: 0

状态码分布:
200    12000
404     1500
500     1000
503      500
Name: status_code, dtype: int64
🔍 关键发现: 状态码 404(未接通)、500(系统错误)、503(服务不可用)合计占比约 20%,这些异常状态码是后续复盘分析的重点对象。同时,duration_sec 在状态码非 200 时均为 0,符合业务逻辑。

2.5 数据源结构总览图

下图展示了从催收系统导出原始数据到初步认识阶段的整体流程与字段结构:

数据源获取与初步认识流程 催收系统导出 CSV / Excel 文件 Pandas 读取 read_csv / read_excel 初步认识 shape / head / dtypes 核心字段结构 case_id 案件编号 phone_number 手机号 contact_time 触达时间 status_code 状态码 质量扫描指标 缺失值统计 isnull() 重复记录 duplicated() 状态码分布 value_counts()

2.6 常见问题与避坑指南

  • 编码问题: 中文 CSV 文件常使用 utf-8 或 gbk 编码。若读取出现乱码,尝试 encoding='gbk' 或 encoding='utf-8-sig'。
  • 日期列类型: 读取后务必检查日期列是否为 datetime64 类型,否则后续时间计算会出错。可使用 pd.to_datetime() 强制转换。
  • 手机号格式: 手机号在 CSV 中可能被 Excel 自动转换为科学计数法,建议导出时设置文本格式,或在读取时指定 dtype={'phone_number': str}。
  • 大文件读取: 若文件行数超过 10 万行,可使用 chunksize 参数分块读取,避免内存溢出。
⚠️ 注意: 不要直接修改原始导出文件。建议在读取后立即创建副本(df_original = df.copy()),以便在清洗过程中随时回溯对比。