4、数据清洗核心概念:缺失值、重复值、异常值、格式不一致、数据类型错误、时间序列问题

金融数据清洗是数据分析流程中最耗时、最影响结论可靠性的环节。金融数据往往来自行情接口、柜台系统、第三方数据库或手工录入,天然带有噪声。本章聚焦六大核心概念——缺失值、重复值、异常值、格式不一致、数据类型错误、时间序列问题,帮助零基础学员建立系统化的清洗认知框架。理解这些概念的本质、识别方法、处理策略和常见误区,是后续学习具体工具(如Python/Pandas、SQL)的基础。

金融数据清洗六大核心概念 缺失值 重复值 异常值 格式不一致 数据类型错误 时间序列问题 识别 → 诊断 → 处理 → 验证 → 记录

上图展示了六大核心概念之间的关系与处理主线。它们并非孤立存在,例如格式不一致可能导致数据类型错误,异常值可能与时间序列中的跳变相关。实际清洗工作中,需要按“识别→诊断→处理→验证→记录”的闭环逻辑推进。下面逐一展开每个概念的原理、判断方法、实战案例与常见误区。

4.1 缺失值

核心原理

缺失值指数据集中某些字段的值为空(NULL、NaN、空字符串等)。金融数据中缺失值产生的原因包括:交易停牌导致行情缺失、手工录入遗漏、系统故障、数据源本身不完整等。缺失值会直接影响统计描述、回归分析和机器学习模型的训练效果,甚至导致模型偏差。

判断方法

  • 直接查看:使用df.info()或df.isnull().sum()快速统计每列缺失数量。
  • 缺失模式分析:判断缺失是随机缺失(MCAR)、与观测值相关(MAR)还是非随机缺失(MNAR)。例如,某股票在停牌期间所有行情字段都缺失,属于结构性缺失。
  • 缺失比例阈值:当某字段缺失超过30%时,通常不建议直接填充,需考虑删除或单独建模。

案例拆解:某券商客户风险评级数据

某券商客户风险测评数据中,“年收入”字段缺失率达25%,“投资经验年限”缺失率8%。直接删除缺失行会损失大量样本,而用均值填充“年收入”会严重扭曲分布(收入呈右偏)。实际操作中,采用分位数分组填充:按客户资产规模分5档,每档内用中位数填充“年收入”;“投资经验年限”则用多重插补法,结合年龄、职业等特征进行预测填充。处理后模型AUC从0.72提升至0.78。

风险提示:金融数据中缺失值处理必须保留处理记录。监管审计时,需要说明缺失比例、填充方法和原因。切勿在未记录的情况下直接删除或填充。

常见误区

  • 误区一:所有缺失值都用均值/中位数填充。对于时间序列数据,前向填充(ffill)或插值法往往更合理。
  • 误区二:忽略缺失值产生的原因。例如,某字段缺失可能代表“无此业务”,而非“数据丢失”,此时应保留为特殊标记。
  • 误区三:填充后不进行敏感性分析。应对比填充前后模型结果,确保结论稳健。

4.2 重复值

核心原理

重复值指数据集中存在完全一致或部分关键字段一致的多条记录。金融数据中重复值可能来自:数据源多次推送、多表合并时未去重、手工录入重复等。重复值会导致统计指标虚高、模型过拟合、交易成本计算错误。

判断方法

  • 完全重复:所有字段完全一致,直接使用df.duplicated()检测。
  • 部分重复:基于业务主键判断,如“交易日期+证券代码+账户ID”唯一时,其他字段重复即为重复记录。
  • 模糊重复:如客户姓名“张三”和“张 三”可能为同一人,需结合相似度算法(如编辑距离)判断。

案例拆解:银行交易流水去重

某银行内部审计时发现,某日交易流水表中有3.2%的记录重复。经排查,原因是核心系统与风控系统双写导致。去重策略:以“交易流水号+交易日期”为唯一键,保留最早一条记录,删除后续重复项。去重后交易总金额下降2.1%,审计差异消除。

经验提醒:去重前务必确认业务唯一键。金融交易中,同一笔交易可能因冲正、撤销产生多条记录,这些不是重复值,而是业务状态变化,不能简单删除。

常见误区

  • 误区一:只做完全去重,忽略部分重复。应结合业务主键定义唯一性。
  • 误区二:去重后不检查数据量变化。若去重比例异常(如超过10%),应回溯数据源。
  • 误区三:去重时保留哪条记录随意选择。应明确规则,如保留最早、最新或数据质量最高的记录。

4.3 异常值

核心原理

异常值(离群点)指明显偏离正常分布的数据点。金融数据中异常值可能是真实的市场极端波动(如2015年A股千股跌停),也可能是数据录入错误(如将100元输成10000元)。区分真实异常与数据错误是清洗的关键。

判断方法

  • 统计方法:3σ原则(均值±3倍标准差)、IQR(四分位距)法,适用于近似正态分布的数据。
  • 业务规则:如股票日涨跌幅不超过±10%(主板),超过即为异常。
  • 可视化方法:箱线图、散点图快速识别离群点。
  • 模型方法:孤立森林、DBSCAN聚类等,适用于多维数据。

案例拆解:基金净值异常检测

某基金公司每日计算基金净值,某日发现某产品净值单日上涨15%,远超同类产品平均0.5%的波动。初步判断为异常值。排查过程:首先检查当日市场行情,确认无重大利好;其次检查估值系统日志,发现某重仓股价格源推送错误(将12.5元推送为125元)。修正价格后,净值恢复至正常水平。此案例说明,异常值处理必须结合业务背景,不能机械地删除或截尾。

风险提示:对于金融时间序列,异常值处理需谨慎。真实的市场极端值(如黑天鹅事件)是重要信息,删除会损失尾部风险特征。建议保留并标记,而非直接删除。

常见误区

  • 误区一:所有异常值都是错误数据。应结合业务场景判断。
  • 误区二:用均值替换异常值。这会降低数据方差,影响风险度量。
  • 误区三:只做单变量异常检测。多维异常(如价格与成交量同时异常)可能更有意义。

4.4 格式不一致

核心原理

格式不一致指同一字段在不同记录中呈现不同的表示形式。金融数据中常见于:日期格式(2024-01-01 vs 2024/1/1 vs 20240101)、货币单位(元 vs 万元 vs 美元)、证券代码(600000.SH vs 600000 vs 600000.SS)、文本大小写(ABC vs abc)等。格式不一致会导致数据无法直接合并、匹配和聚合。

判断方法

  • 字段值域检查:使用df['字段'].unique()查看所有唯一值,人工识别格式差异。
  • 正则表达式匹配:如日期字段,用\d{4}-\d{2}-\d{2}匹配标准格式,找出不匹配的记录。
  • 长度检查:如证券代码应为6位数字,长度不符即为格式异常。

案例拆解:多源行情数据合并

某量化团队从Wind、Choice和交易所官网获取股票日行情。三个数据源的日期格式分别为“2024-01-01”、“2024/1/1”和“20240101”,证券代码分别为“600000.SH”、“600000”和“600000.SS”。合并前需统一格式:日期统一为YYYY-MM-DD,证券代码统一为“600000.SH”格式(交易所后缀大写)。处理后,三源数据可正常按日期和代码匹配,合并后数据量从单源的5000条增至15000条(含不同源交叉验证)。

经验提醒:格式统一应在数据读取阶段完成,而非分析阶段。建议建立数据字典,明确每个字段的标准格式,并在清洗流程中自动校验。

常见误区

  • 误区一:只统一显示格式,不统一存储格式。例如日期显示为“2024-01-01”但存储为字符串,无法进行时间运算。
  • 误区二:忽略编码问题。如中文乱码、UTF-8与GBK混用。
  • 误区三:格式统一后不验证。应抽样检查转换后的数据是否与原值等价。

4.5 数据类型错误

核心原理

数据类型错误指字段的存储类型与业务含义不符。金融数据中常见:数值字段存储为字符串(如“1,234.56”)、日期字段存储为字符串、布尔字段存储为0/1但被识别为整数等。数据类型错误会导致计算错误、排序异常、聚合结果偏差。

判断方法

  • 使用df.dtypes:检查每列的数据类型。
  • 尝试转换:用pd.to_numeric()、pd.to_datetime()尝试转换,观察是否报错或产生NaN。
  • 业务逻辑验证:如“交易金额”字段出现负数,虽然类型为float,但业务上金额不应为负(除非是冲正记录)。

案例拆解:P2P平台逾期率计算错误

某P2P平台计算逾期率时,发现结果异常偏高。排查发现,“逾期天数”字段被存储为字符串类型,且部分值包含“天”字(如“15天”)。在计算逾期率时,字符串无法直接参与数值比较,导致所有非空值都被视为逾期。修复方法:提取字符串中的数字部分,转换为整数类型,再重新计算。修复后逾期率从45%降至8%,与业务实际相符。

风险提示:数据类型错误往往隐蔽性强,尤其在数据量大的时候。建议在数据加载后立即进行类型检查,并设置类型断言(如金额必须为float且大于0)。

常见误区

  • 误区一:忽略“object”类型字段。object类型可能是字符串、混合类型或Python对象,需逐一检查。
  • 误区二:强制转换导致数据丢失。如将“1,234.56”直接astype(float)会报错,需先去除千分位逗号。
  • 误区三:转换后不检查范围。如将日期字符串转换为datetime后,可能出现1900-01-01等异常值。

4.6 时间序列问题

核心原理

时间序列问题特指与时间索引相关的数据质量问题,包括:时间戳重复、时间间隔不规律、时区不一致、交易日历不匹配、时间戳精度不一致(秒级vs毫秒级)等。金融数据高度依赖时间顺序,时间序列问题会导致回测结果失真、信号延迟、风险指标计算错误。

判断方法

  • 时间排序检查:确认时间戳是否严格递增。
  • 频率检查:使用df.index.to_series().diff()查看时间间隔分布,判断是否存在缺失时间点。
  • 时区检查:确认所有时间戳是否在同一时区,或是否已标注时区信息。
  • 交易日历匹配:金融数据应匹配交易所交易日历,非交易日的数据可能是错误或特殊事件。

案例拆解:高频交易回测时间对齐

某高频策略团队使用Level-2逐笔委托数据回测。原始数据时间戳为交易所服务器时间(UTC+8),但策略服务器使用UTC时间。直接回测导致所有信号延迟8小时,策略表现极差。修复方法:将时间戳统一转换为UTC+8,并重采样至毫秒级精度。同时发现,部分交易日数据存在时间戳重复(同一毫秒多条记录),按“接收序号”字段进行二次排序。修复后回测结果与实盘表现基本一致。

经验提醒:时间序列清洗应建立“时间质量报告”,包括:时间范围、最小/最大间隔、重复时间戳数量、缺失时间段等。该报告应作为每次数据更新的标准产出物。

常见误区

  • 误区一:忽略时区问题。跨境金融数据尤其需要注意,如美股数据使用美东时间,A股使用北京时间。
  • 误区二:重采样时使用错误方法。如将日线数据重采样为周线时,应使用“最后交易日”而非“周五”作为周标签。
  • 误区三:不处理时间戳精度不一致。如部分数据精确到秒,部分精确到毫秒,合并时需统一精度。

4.7 六大概念综合对比与清洗流程

概念 典型表现 识别方法 常用处理策略 金融场景示例
缺失值 字段为空、NaN isnull()统计、缺失模式分析 删除、填充(均值/中位数/前向)、插值、多重插补 停牌股票行情缺失
重复值 完全重复或主键重复 duplicated()、业务主键检查 删除重复项、保留指定记录 多系统双写导致流水重复
异常值 偏离分布、超出业务范围 3σ、IQR、箱线图、业务规则 修正、截尾、标记保留 价格源推送错误导致净值跳变
格式不一致 日期/代码/单位表示多样 unique()值域检查、正则匹配 统一格式、标准化映射 多源行情数据合并
数据类型错误 数值存为字符串、日期存为文本 dtypes检查、尝试转换 类型转换、提取数字、解析日期 逾期天数含“天”字导致计算错误
时间序列问题 时间戳重复、时区不一致、频率不规律 diff()间隔检查、时区核对 排序、重采样、时区转换、日历匹配 高频回测时间偏移8小时

综合来看,六大概念在实际数据中往往交织出现。例如,格式不一致可能导致数据类型错误,异常值检测时需先排除缺失值干扰。建议清洗流程遵循以下顺序:先处理缺失值(确定删除或填充策略),再处理重复值(去重),然后检查数据类型并统一格式,接着进行异常值检测与处理,最后专门处理时间序列问题。每一步处理后都应输出清洗报告,记录处理前后数据量、关键字段统计量变化,确保清洗过程可追溯、可复现。

总结复盘:数据清洗不是一次性任务,而是持续迭代的过程。金融数据源会不断更新,新的质量问题会持续出现。建议建立自动化清洗管道,将上述六大类检查固化为脚本,每次数据更新后自动运行并生成质量报告。同时,保留原始数据备份,任何清洗操作都应在副本上进行,确保原始数据可追溯。