数据没有报错,为什么仍然可能不能信?

数据质量与校验:缺失、异常、口径

约 9 分钟5 道自测更新于 2026-10-29

一句话记住数据质量不是只查格式,而是用可执行规则检查完整性、合法性、业务关系、及时性和口径。

01学完你能做到

  • 按完整性、唯一性、有效性、一致性、准确性、及时性和口径检查数据。
  • 区分必须拦截的错误与需要人工复核的异常。
  • 为行情数据设计可自动执行的校验规则。

02这课解决什么问题

一根 K 线的最高价低于收盘价、某只股票缺失、成交量单位从股变成手,怎样在数据发布前发现,而不是等用户回测得出错误结论后才发现?

03质量维度

  • 完整性:该有的数据是否都在,例如证券列表中的股票是否都有对应交易日数据。
  • 唯一性:主键是否重复,例如同一代码、同一交易日是否出现两条日 K。
  • 有效性:值是否在合法范围,例如价格大于 0、比例在约定范围内、日期格式正确。
  • 内在一致性:字段之间的关系是否成立,例如 high 不低于 open 和 close,low 不高于它们。
  • 准确性:与权威来源或第二来源是否一致,通常需要抽样或重点字段对账。
  • 及时性:是否在承诺时间内到达,时间戳是否对应正确的交易日和时区。
  • 口径一致:单位、复权方式、资产范围和字段含义是否前后一致。

规则不通过不等于数据必错。某个市场涨跌幅较大,可能是正常交易制度允许的结果。应把确定性错误设为“拦截”,把可疑但可能真实的结果设为“告警”,并保留复核依据。规则还要带生效日期,因为交易制度和字段口径可能变化。

04分层校验

接入:格式、字段、行数、重复、空值
  ↓
加工后:OHLC 关系、均价范围、跨日衔接、涨跌幅
  ↓
发布后:与另一来源对账、延迟监控、修正追踪

越早发现问题,修复成本越低;但只做接入检查还不够,业务加工后仍可能产生新问题。

05一个最小例子

import pandas as pd

df = pd.read_csv("bars.csv", dtype={"code": str})
for col in ["open", "high", "low", "close", "volume", "turnover"]:
    df[col] = pd.to_numeric(df[col], errors="coerce")

checks = {
    "duplicate_key": int(df.duplicated(["code", "trade_date"]).sum()),
    "missing_row": int(df.isna().any(axis=1).sum()),
    "bad_ohlc": int((
        (df.high < df[["open", "close"]].max(axis=1)) |
        (df.low > df[["open", "close"]].min(axis=1)) |
        (df[["open", "high", "low", "close"]] <= 0).any(axis=1)
    ).sum()),
}

active = df[df.volume > 0].copy()
active["vwap"] = active.turnover / active.volume
checks["vwap_outside_range"] = int(
    (~active["vwap"].between(active.low, active.high)).sum()
)
print(checks)

成交额 ÷ 成交量得到的均价应落在当日最低价和最高价之间。这条规则既能查异常,也能帮助发现“股”和“手”混用的单位错误。真实生产环境还要明确停牌、无成交、上市首日和不同板块规则等例外。

06常见误区

  1. 只查字段类型和空值,不查 OHLC 关系、均价范围等业务关系。
  2. 把所有异常都拦截,误删真实的极端行情。
  3. 规则写死,不记录生效日期,制度变化后产生大量误报或漏报。
  4. 只逐行检查,不和证券列表、交易日历等外部参照比较,因此发现不了整只股票缺失。
  5. 只在入库时检查一次,不监控上游事后修正和发布后的对账结果。
  6. 修正数据却不保留修正记录,导致用户无法解释历史结果为什么变化。

07延伸阅读

08一分钟讲给别人

试着用自己的话讲一遍数据质量不是看 CSV 能不能打开,而是检查它是否完整、唯一、合法、及时,字段之间是否符合业务关系。最高价不能低于收盘价,成交额除以成交量得到的均价应落在高低价之间。涨幅很大不一定是错,所以确定性错误拦截、可疑结果告警,规则还要记生效时间。

想一想

5 道自测

先在心里答一遍,再展开对照。能说清理由,比答对数字更重要。

  1. 01逐行检查为什么发现不了少了一只股票?

  2. 02如何用均价范围检查成交量单位?

  3. 03异常和错误有什么区别?

  4. 04为什么规则要带生效日期?

  5. 05拦截和告警分别适合什么情况?

已看 0/5 题

练动手练习

任务:为日 K 数据增加三条规则:和证券列表比较股票数量、检查昨收与前一交易日衔接、按资产类型应用不同的涨跌幅规则。把结果分成 block 和 warn 两级,并记录规则版本。

完成这一课

完成这一课

读完讲义、看完自测答案,这一课就算学完了。

  • 读完讲义
  • 看完全部自测

本课为投资者教育内容,案例数字均为示意,不构成任何投资建议,也不承诺收益。规则和费率会变,实际操作前请以交易所、监管机构和产品的最新公告为准。