深圳融克迪特科技有限公司 Logo,金融科技,量化交易,软件开发

深圳融克迪特科技有限公司

RONG CREDIT TECHNOLOGY CO., LTD.

基础入门

【pandas 系列 第3讲】新增收益率列

在收盘价列基础上新增最基础的日收益率列,理解 pct_change 的含义、第一行空值的来源,以及如何把原始价格表推进为带衍生指标的分析表。

2026-04-23 智铨研究 阅读时长 5 分钟

目录

  1. 本节目标
  2. 为什么第 3 讲先新增收益率列
  3. 沿用第 2 讲的work_df
  4. 四步新增收益率列
  5. 先确认close是数值列
  6. 使用pct_change()计算收益率
  7. 只把关键列打印出来看
  8. 观察第一行空值
  9. 怎样判断收益率列已经加对了
  10. 新列已经存在
  11. 第一行为空是正常现象
  12. 后续行至少有一部分出现有效值
  13. 价格与收益率可以并排查看
  14. 为什么收益率列看着有点奇怪
  15. 第一行是 NaN
  16. 收益率值很小
  17. 出现很多 NaN
  18. 为什么不直接乘以 100
  19. 哪些情况仍然算本讲完成
  20. 写一个最小收益率函数
  21. 第 3 讲开始让表“长出分析列”
  22. 完成标准
  23. 系列衔接
  24. 风险揭示与免责声明

【pandas 系列 第3讲】新增收益率列

1. 本节目标

第 3 讲开始第一次在 work_df 上新增一列真正有分析意义的结果:日收益率。目标不是一下子讲清所有收益率定义,而是先让你把“收盘价列”推进成“价格列 + 一列可解释的新指标”。

学完这一讲后,你可以直接完成下面几件事:

  1. 知道为什么收益率通常从 close 列开始算。
  2. 会用 pandas 生成一列最基础的日收益率。
  3. 理解第一行为什么通常是空值。

这一步是 pandas 金融数据练习里最自然的一次升级,因为它让你第一次从“看表”走向“在表上算出新列”。

2. 为什么第 3 讲先新增收益率列

收盘价本身当然重要,但很多真正的金融分析并不直接拿价格做比较,而更关心价格变化幅度。收益率正好是最适合入门的第一列衍生指标,因为它:

  1. 只依赖一列 close,输入简单。
  2. 结果容易解释,是“今天相对昨天涨跌了多少”。
  3. 后面不管做月度统计、均线、回测还是简单筛选,都很常继续用到。

所以第 3 讲不是在追求复杂公式,而是在帮你建立一种新意识:DataFrame 不只是被读取和筛选,它还可以逐步长出新的分析列。

3. 沿用第 2 讲的work_df

work_df = work_df.copy()
print(work_df.head())

当前这张表里至少应该有三列:

其中最关键的是 close。因为第 3 讲的收益率列完全建立在它之上。

4. 四步新增收益率列

这一讲的顺序最好固定下来:先确认价格列能参与计算,再生成新列,然后把新列和原始价格并排看,最后确认空值位置是否符合预期。

5. 先确认close是数值列

print(work_df['close'].dtype)

如果 close 还是字符串或混合类型,后面收益率就可能算不出来。最稳的做法是先显式转型:

work_df['close'] = pd.to_numeric(work_df['close'], errors='coerce')

6. 使用pct_change()计算收益率

work_df['return'] = work_df['close'].pct_change()
print(work_df.head())

这是第 3 讲最核心的一行。pct_change() 的含义非常直观:当前值相对上一行变化了多少比例。

7. 只把关键列打印出来看

print(work_df[['date', 'close', 'return']].head())

一定要把原始价格和新列并排看,这样你才能确认这列新结果到底在表达什么,而不是只看到一串小数。

8. 观察第一行空值

print(work_df['return'].head(3))

第一行通常会是空值,因为它前面没有“上一天”可比。这不是错误,反而是收益率列最应该理解的第一层逻辑。

9. 怎样判断收益率列已经加对了

收益率列是否可信,不看它是不是“生成了数字”,而看它有没有满足最基本的结构特征:列存在、首行为空、后面开始出现有效值。

10. 新列已经存在

assert 'return' in work_df.columns

11. 第一行为空是正常现象

assert work_df['return'].isna().iloc[0]

12. 后续行至少有一部分出现有效值

assert work_df['return'].notna().sum() > 0

13. 价格与收益率可以并排查看

print(work_df[['date', 'close', 'return']].head())

14. 为什么收益率列看着有点奇怪

收益率是这套短课里第一次真正意义上的衍生列,所以很多初学者第一次看到它时都会觉得不如价格列直观。下面这些现象大多不是错误,而是它的正常表现。

15. 第一行是 NaN

这是正常的,因为没有前一天可比较。

16. 收益率值很小

这通常也是正常的。日收益率往往就是几个百分点以内,写成小数时看起来会比较小。

17. 出现很多 NaN

这通常说明 close 列本身就有空值,或者类型没有先处理好。此时应该回头看第 2 讲的筛选和本讲第一步的转型。

18. 为什么不直接乘以 100

可以乘,但第 3 讲不建议一开始就这么做。保留原始小数收益率,对后续计算更自然,也更符合 pandas 常见用法。

19. 哪些情况仍然算本讲完成

  1. 你把列名叫成 ret 也可以,只要自己清楚含义。
  2. 第一行空值不算失败。
  3. 当前只算简单日收益率,不必区分对数收益率和普通收益率。
  4. 你暂时不删除第一行空值也没关系,第 4 讲再继续处理缺失值。

20. 写一个最小收益率函数

import pandas as pd

def add_daily_return(df: pd.DataFrame) -> pd.DataFrame:
    out = df.copy()
    out['close'] = pd.to_numeric(out['close'], errors='coerce')
    out['return'] = out['close'].pct_change()
    return out

work_df = add_daily_return(work_df)
print(work_df[['date', 'close', 'return']].head())

21. 第 3 讲开始让表“长出分析列”

前两讲更多是在把数据读进来、缩清楚;到了第 3 讲,你第一次真正给这张表加上了新的分析含义。以后无论你算均线、波动率还是分组统计,本质上都是在继续扩展这种“原始列 + 衍生列”的工作方式。

22. 完成标准

如果你现在已经能稳定在 close 基础上新增一列 return,并理解为什么第一行会为空,那第 3 讲就算完成。

23. 系列衔接

本讲是《pandas金融数据入门短课》的第 3/8 讲,当前主题是《新增收益率列》。

上一讲:第 2 讲《选列筛行:保留日期收盘价和成交量》。

下一讲:第 4 讲《处理缺失值》。

后续安排:第 5 讲《排序并重置索引》;第 6 讲《计算5日和10日均线》。

24. 风险揭示与免责声明

风险揭示与免责声明

本页面内容仅用于量化研究与技术交流,旨在展示研究方法与流程,不构成对任何金融产品、证券或衍生品的要约、招揽、推荐或保证。

本文所涉历史数据、回测结果与示例参数不代表未来表现,也不应作为投资决策依据。

市场存在波动、流动性与执行偏差等不确定性,任何策略均可能出现收益波动或阶段性失效。

读者应结合自身风险承受能力进行独立判断,并在必要时咨询持牌专业机构意见。