3. 数据概览与基础统计:快速摸清数据全貌
在开始任何数据清洗工作之前,第一步永远是“摸清家底”。面对催收触达的原始数据,我们需要快速回答三个核心问题:数据有多大?、哪些字段有缺失?、字段类型是否合理?。Pandas 提供了三个最基础、最高效的方法:shape、info() 和 describe()。
3.1 数据规模:shape 与 len
使用 df.shape 可以立即获取 DataFrame 的行数和列数,这是对数据体量的第一印象。
import pandas as pd
# 假设已加载原始催收数据
df = pd.read_csv('collection_contact_raw.csv')
# 查看数据规模
rows, cols = df.shape
print(f"数据集包含 {rows} 行记录,{cols} 列字段。")
💡 实战提示: 催收数据通常按天或按批次导出,行数在几万到几十万之间。如果行数异常少(如 0 行),需立即检查上游数据源是否为空或导出失败。
3.2 数据类型与缺失值:info() 全景扫描
df.info() 是数据清洗中最常用的“体检报告”。它会一次性输出:列名、非空计数、数据类型(Dtype)以及内存占用。
# 打印数据集的完整信息
df.info()
输出示例(模拟):
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 50000 entries, 0 to 49999
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 客户ID 50000 non-null int64
1 催收员ID 49800 non-null float64
2 触达时间 50000 non-null object
3 触达方式 50000 non-null object
4 通话时长(秒) 42000 non-null float64
5 是否接通 50000 non-null object
6 承诺还款金额 15000 non-null float64
7 承诺还款日期 12000 non-null object
8 客户标签 30000 non-null object
9 案件金额 50000 non-null int64
10 逾期天数 50000 non-null int64
11 催收结果备注 25000 non-null object
dtypes: float64(3), int64(3), object(6)
memory usage: 4.6+ MB
3.3 关键字段解读:从 info() 中发现的异常
通过上述 info() 输出,我们可以快速定位以下潜在问题:
| 字段名 | 问题类型 | 异常描述 | 清洗优先级 |
|---|---|---|---|
| 催收员ID | 缺失值 + 类型错误 | 有 200 个缺失值;应为字符串(object),但显示为 float64 | 高 |
| 通话时长(秒) | 缺失值 | 缺失 8000 条(16%),需判断是未接通还是数据丢失 | 高 |
| 承诺还款金额 | 高缺失率 | 仅 30% 有值,需评估是否用于建模 | 中 |
| 触达时间 | 类型错误 | 显示为 object,实际应为 datetime 类型 | 高 |
⚠️ 常见陷阱: 催收员ID、案件ID 等标识字段,如果被 Pandas 自动识别为 float64,说明该列存在缺失值(NaN)。必须将其转换为字符串类型,否则后续关联分析会出错。
3.4 数值分布概览:describe() 快速统计
df.describe() 对数值型列自动计算:计数、均值、标准差、最小值、四分位数和最大值。这是发现异常值的“雷达”。
# 查看数值列的统计摘要
df.describe()
输出示例(模拟):
案件金额 逾期天数 通话时长(秒)
count 50000.00 50000.00 42000.00
mean 8500.50 45.30 120.50
std 3200.20 30.10 98.40
min 500.00 1.00 0.00
25% 6200.00 20.00 30.00
50% 7800.00 38.00 95.00
75% 10200.00 65.00 180.00
max 50000.00 180.00 600.00
3.5 从 describe() 中识别异常信号
- 通话时长(秒): 最小值为 0,但催收通话不可能为 0 秒。这通常代表未接通或挂断记录,需要结合“是否接通”字段进行过滤或填充。
- 案件金额: 最大值 50000 远高于 75% 分位数的 10200,可能存在极端大额案件,需确认是否为数据录入错误或真实高额案件。
- 逾期天数: 最大值 180 天,需确认是否超过业务定义的催收周期上限。
📌 清洗行动清单:
- 将“催收员ID”转为字符串,并处理缺失值。
- 将“触达时间”转为 datetime 格式。
- 对“通话时长”为 0 的记录,标记为“未接通”或填充为 NaN。
- 检查“案件金额”和“逾期天数”的极端值是否合理。
3.6 数据概览流程总图
以下 SVG 图展示了从加载数据到生成清洗清单的完整概览流程:
3.7 非数值列的快速探查
对于 object 类型的列(如“触达方式”、“催收结果备注”),describe() 默认不统计。我们可以使用 value_counts() 来查看分类分布:
# 查看触达方式的分布
print(df['触达方式'].value_counts())
# 查看是否接通的分布
print(df['是否接通'].value_counts())
输出示例:
触达方式
电话外呼 35000
短信通知 10000
AI外呼 5000
Name: count, dtype: int64
是否接通
是 28000
否 22000
Name: count, dtype: int64
💡 业务洞察: 电话外呼占比 70%,但接通率仅 56%(28000/50000)。这提示我们需要重点关注“未接通”记录的清洗策略,例如是否保留、如何标记原因。