01学完你能做到
说明 DataFrame 中每行和每列的业务含义;正确使用筛选、分组、变形和连接;识别类型混杂、重复键、标签错位和缺失记录造成的静默错误。
02这课解决什么问题
DataFrame 能创建成功,为什么不代表数据已经可以放心计算?金融数据最容易出错的地方,是一行代表什么没有说清、连接后行数悄悄变多,或缺失被当成正常数字。
03DataFrame、列类型与索引
DataFrame 是带行列标签的二维表;Series 是一维带标签数据结构;Index 是行标签。Index 可以重复,不能直接当数据库唯一键。
pandas 一列通常有一个 dtype,但 object 列内部可能混有整数和字符串。把表创建出来,不等于价格已经是有效数值。金融字段还需要业务约束:证券代码保留字符串和市场语义,成交量标明股或手,价格注明原始或复权口径,缺失、零值和不可用状态分开表示。
先写“一行的含义”。例如日行情长表可以约定一行等于“某来源、某价格口径下,一只证券在一个交易日的一个版本”。如果有多个来源或修订版本,仅代码加日期可能不唯一。
04四个常用动作
筛选与分组
筛选回答“哪些记录符合条件”;groupby 回答“哪些记录应分别计算”。算收益前先检查证券和日期键,再按证券分组、按时间排序。pct_change 比较相邻观测行,不会自动确认两天是否为相邻交易日。
结果 0.02 表示 2%,不是 0.02%。计算时保留精度,展示时再四舍五入;过早舍入可能改变阈值筛选。
长表与宽表
长表适合保留证券、日期、来源和状态;宽表适合同一时点的多证券比较。pivot 要求索引和列的组合唯一;重复键应先调查来源、修订或输入错误,不能用平均值把冲突隐藏掉。melt 能把宽表变成长表,但不会自动恢复已经丢掉的来源和版本信息。
连接与标签对齐
merge 可以按普通列或索引连接。连接主表时,若行情表多行对应主表一行,可用 validate="many_to_one" 检查。右表重复键会放大行数,成交量和计数可能因此翻倍。
Series 运算按标签对齐,而不是按屏幕行位置。例如左表 A=1、B=2,右表顺序是 B=10、A=20,相加结果仍是 A=21、B=12。pandas 的 merge 对两边空键的处理也要单独确认,不能直接套用其他数据库的直觉。
05代码:先校验再计算
import pandas as pd
df = pd.DataFrame({
"date": pd.to_datetime(["2026-10-21", "2026-10-22", "2026-10-23"] * 2),
"instrument_id": ["DEMO_A"] * 3 + ["DEMO_B"] * 3,
"close": [10.0, 10.2, 9.9, 12.0, 12.6, 12.5],
"volume": [1000, 1500, 800, 2000, 2600, 1800],
})
keys = ["instrument_id", "date"]
assert not df.duplicated(keys).any()
for col in ["close", "volume"]:
df[col] = pd.to_numeric(df[col], errors="raise")
assert df["close"].gt(0).all() and df["volume"].ge(0).all()
df = df.sort_values(keys)
df["ret"] = df.groupby("instrument_id")["close"].pct_change(fill_method=None)
master = pd.DataFrame({"instrument_id": ["DEMO_A", "DEMO_B"], "currency": ["CNY", "CNY"]})
joined = df.merge(master, on="instrument_id", how="left",
validate="many_to_one", indicator=True)
assert len(joined) == len(df)
print(joined)教学代码用 assert 表达快速检查;生产服务应使用显式校验、错误记录和告警,因为某些运行选项可能禁用断言。
06四类需要重点审查的错误
- 行数悄悄变多:连接前后记录数、匹配率和键唯一性都要记录。
- 用今天的主数据解释过去:历史分类、上市状态和证券名称可能需要生效区间;时间可用性不能被忽略。
- 缺失记录被跳过:跨过多个交易日的两条价格仍会产生数字,但不能无条件叫作单日收益。
- 接口类型不稳定:数字、空字符串和不同时间格式混在一起,会让下游解析不稳定。应明确 schema、缺失约定、单位和版本兼容规则。
07工具选择的基本判断
| 工具 | 常见特点 | 需要验证 |
|---|---|---|
| pandas | 单机内存处理,标签对齐语义重要 | 内存峰值、类型、索引和耗时 |
| Polars | 表达式和惰性执行,部分场景可流式处理 | 操作覆盖、转换成本和实际性能 |
| Spark DataFrame | 分区执行,可进行分布式计算 | 数据规模、shuffle、资源和运维成本 |
不要只凭“数据有多少 GB”决定技术栈。先减少无用列、过滤日期、检查类型和分区读取,再用真实查询压测。
08延伸阅读
09一分钟讲给别人
试着用自己的话讲一遍DataFrame 帮我们把同一种操作重复执行,但计算前要先说明每行含义和键。算收益先分组排序,还要查缺失日期;连接要检查唯一性和行数;数字类型、单位和价格口径都要确认。
5 道自测
先在心里答一遍,再展开对照。能说清理由,比答对数字更重要。
01为什么 Index 不能直接当数据库唯一键?
02`pct_change` 为什么不能自动证明结果是“单日收益”?
03`merge` 后行数变多,最常见的原因是什么?
04为什么不能用平均值直接消除重复键?
05Series 运算按什么规则对齐?
已看 0/5 题
练动手练习
任务:在样本中复制 DEMO_A 的第二天记录,先预测哪个检查会失败,再运行。然后把一个 close 改成“暂停”,说明错误信息至少应包含字段、记录标识、原始值和预期类型。
完成这一课
读完讲义、看完自测答案,这一课就算学完了。
- 读完讲义
- 看完全部自测
本课为投资者教育内容,案例数字均为示意,不构成任何投资建议,也不承诺收益。规则和费率会变,实际操作前请以交易所、监管机构和产品的最新公告为准。