← 返回《量化交易 Python 入门:从咖啡馆到华尔街》
📑 查看全课大纲(第 42 / 52 节)
  1. 1.量化分析基本概念:从咖啡馆到华尔街
  2. 2.量化交易员学习路线:从零基础到策略开发
  3. 3.量化策略生命周期:数据分析的五大流程
  4. 4.量化数据类型:数值型与类别型数据
  5. 5.量化沙盒搭建(1):Python与Anaconda安装
  6. 6.量化沙盒搭建(2):Jupyter Notebook与库配置
  7. 7.本地多源数据:量化历史回测的基石
  8. 8.TXT数据流操作:处理金融交易日志
  9. 9.JSON数据流操作:解析股票行情API响应
  10. 10.CSV行情文件操作:读取与存储历史K线
  11. 11.Excel报表操作:清洗财报与财务指标
  12. 12.量化数据库:SQL常用查询语法
  13. 13.量化数据库:Python连接与写入
  14. 14.量化多表连接:关联股票信息与行情
  15. 15.实战:小象咖啡店营业数据与个股财务指标的多源数据分析
  16. 16.量化数据采集:爬虫工作原理与合规
  17. 17.量化爬虫核心:URL管理与去重策略
  18. 18.量化网页下载:防反爬与请求头伪装
  19. 19.网页解析(1):使用XPath定位财经新闻
  20. 20.网页解析(2):使用CSS选择器与ItemLoader
  21. 21.Scrapy框架:构建工业级量化爬虫
  22. 22.Scrapy实战(1):新建项目与数据模型定义
  23. 23.Scrapy实战(2):编写财经爬虫逻辑
  24. 24.Scrapy实战(3):启用数据管道清洗行情
  25. 25.Scrapy实战(4):防反爬中间件配置
  26. 26.实战:构建每日热门个股行情自动采集系统
  27. 27.NumPy与SciPy:加速量化矩阵计算
  28. 28.NumPy数组:构建股票价格矩阵
  29. 29.数组切片:提取特定股票与交易日数据
  30. 30.NumPy常用方法:计算均值与波动率
  31. 31.向量化计算:摆脱缓慢的For循环
  32. 32.通用函数ufunc:计算对数收益率与累计收益
  33. 33.实战:股票组合资产收益率与协方差矩阵计算
  34. 34.Pandas Series:管理单只股票收盘价
  35. 35.Pandas DataFrame:构建多只股票行情面板
  36. 36.Pandas Index:时间序列索引与对齐
  37. 37.Series索引操作:按位置与标签访问行情数据
  38. 38.DataFrame索引操作:loc与iloc定位行情
  39. 39.索引总结:量化多字段筛选与定位
  40. 40.运算与对齐:合并不同交易日的数据
  41. 41.Pandas map:对股票代码与状态做映射
  42. 42.Pandas apply:滚动计算技术指标
  43. 43.文件读写操作:CSV行情数据导入导出
  44. 44.排序操作:按市盈率与收益率对股票排名
  45. 45.数据清洗:填充与剔除停牌股票缺失值
  46. 46.数据清洗:剔除重复报价与异常交易数据
  47. 47.数据清洗:替换异常报价数据
  48. 48.常用统计:量化最大回撤与分位数风险评估
  49. 49.常用统计:sum/mean/median/count聚合指标
  50. 50.极值定位:寻找历史最高价与最低价的发生日
  51. 51.风险与累计收益:计算年化波动率与累计回报
  52. 52.实战:小象咖啡店营业数据与热门个股时间序列清洗分析

Pandas apply:滚动计算技术指标

Pandas apply:滚动计算技术指标

小象量化极客小册 · 华尔街量化分析先锋系列

Pandas 是量化交易员最核心的武器。本节你将通过 Series 和 DataFrame 深度处理时间序列行情数据,掌握 loc/iloc 定位筛选、缺失值与重复值清洗、以及最大回撤与年化波动率等核心指标统计计算。

小象量化极客小册 · 华尔街量化分析先锋系列 Pandas 是量化交易员最核心的武器。本节你将通过 Series 和 DataFrame 深度处理时间序列行情数据,掌握 loc/iloc 定位筛选、缺失值与重复值清洗、以及最大回撤与年化波动率等核心指标统计计算。

💡 核心导读

本节将深入讲解 Pandas 中两个核心函数应用方法:apply()applymap()。通过学习,您将掌握如何对 DataFrame 的行列进行批量操作(apply),以及如何对每个元素进行标量处理(applymap)。重点包括:理解轴方向的应用逻辑、性能优化技巧,以及在实际数据清洗/特征工程中的应用场景。我们将通过销售数据分析的完整案例,演示如何用这两种方法实现数据标准化、异常值处理和特征生成。


apply() 方法详解

基本概念与轴向操作

apply() 是 Pandas 最强大的函数应用方法,可沿特定轴(0=列,1=行)应用函数:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    '销售额': [120, 150, 200, 90],
    '成本': [80, 100, 130, 70]
}, index=['Q1', 'Q2', 'Q3', 'Q4'])

print(df.apply(np.mean, axis=0))

print(df.apply(lambda x: x.sum(), axis=1))

复杂函数应用

可封装自定义函数处理整行/列数据:

def profit_margin(row):
    return (row['销售额'] - row['成本']) / row['销售额'] * 100

df['利润率'] = df.apply(profit_margin, axis=1)
print(df)

执行前后数据结构对比:

   销售额   成本
Q1   120   80
Q2   150  100
Q3   200  130
Q4    90   70

   销售额   成本        利润率
Q1   120   80  33.333333
Q2   150  100  33.333333
Q3   200  130  35.000000
Q4    90   70  22.222222

💡 概念小测:apply 的性能

在处理 1000 万行的股票行情 DataFrame 时,如果在每一行上使用 .apply(lambda x: custom_func(x), axis=1) 逐行计算指标,为什么这通常是量化代码的严重性能瓶颈

  • 因为 Pandas 不支持在 1000 万行数据上运行 apply。
  • axis=1 的 apply 实际上是在 Python 层面逐行循环,相当于没有利用任何 Pandas/NumPy 底层的 C 加速。
  • 因为 lambda 匿名函数会在内存中产生严重的泄露。
  • apply 无法获取各列数据,只能获得行索引。

📝 选择题

💡 概念小测:apply 的性能 在处理 1000 万行的股票行情 DataFrame 时,如果在每一行上使用 .apply(lambda x: custom_func(x), axis=1) 逐行计算指标,为什么这通常是量化代码的严重性能瓶颈

  • A. 因为 Pandas 不支持在 1000 万行数据上运行 apply。
  • B. axis=1 的 apply 实际上是在 Python 层面逐行循环,相当于没有利用任何 Pandas/NumPy 底层的 C 加速。
  • C. 因为 lambda 匿名函数会在内存中产生严重的泄露。
  • D. apply 无法获取各列数据,只能获得行索引。

答案:Baxis=1 的 apply 实际上是在 Python 层面逐行循环,相当于没有利用任何 Pandas/NumPy 底层的 C 加速。)


applymap() 元素级处理

方法特性与适用场景

applymap() 对 DataFrame 每个元素执行标量函数操作:

df = pd.DataFrame({
    'A': [1.12, 2.34, np.nan],
    'B': [4.56, np.nan, 6.78]
})

processed_df = df.applymap(
    lambda x: f"{x:.2f}" if not pd.isna(x) else "NULL"
)
print(processed_df)

性能对比建议

  • 优先使用内置向量化方法(如 df * 2
  • 简单逻辑用 applymap,复杂逻辑考虑 apply
  • 大数据量时考虑并行化处理


综合应用案例

销售数据清洗实战

sales = pd.DataFrame({
    '产品': ['A', 'B', 'C', 'D'],
    '单价': ['¥120', '150元', '98.5', '200$'],
    '销量': [45, '62', 78, 'N/A']
})

def clean_price(text):
    if isinstance(text, str):
        return float(''.join(filter(str.isdigit, text)))
    return float(text)

def clean_quantity(val):
    if str(val).isdigit():
        return int(val)
    return 0

sales['单价'] = sales['单价'].apply(clean_price)
sales['销量'] = sales['销量'].apply(clean_quantity)
sales['销售额'] = sales.apply(lambda r: r['单价'] * r['销量'], axis=1)

print(sales)

处理结果:

  产品    单价  销量    销售额
0  A  120.0  45  5400.0
1  B  150.0  62  9300.0
2  C   98.5  78  7683.0
3  D  200.0   0     0.0

💡 代码填空:按列计算均值

补全代码,使用 apply 方法按列(即计算 AAPL 和 GOOG 每只股票各自)的平均价格:

import pandas as pd

df = pd.DataFrame({'AAPL': [150, 152], 'GOOG': [2700, 2710]})
col_means = df.{blank}(lambda x: x.mean())
print(col_means['AAPL']) # 输出 151.0
  • map
  • apply
  • applymap

✏️ 填空题

💡 代码填空:按列计算均值 补全代码,使用 apply 方法按列(即计算 AAPL 和 GOOG 每只股票各自)的平均价格:

import pandas as pd
df = pd.DataFrame({'AAPL': [150, 152], 'GOOG': [2700, 2710]})
# apply 默认按列 (axis=0) 计算
col_means = df.___(lambda x: x.mean())
print(col_means['AAPL']) # 输出 151.0

答案:apply


本章小结

行动清单

  • 使用 apply() 计算 DataFrame 每行的变异系数(标准差/均值)
  • 用 applymap() 实现电话号码脱敏处理(如 13812345678 → 138****5678)
  • 在泰坦尼克数据集上,应用 apply 方法创建”家庭成员数”特征(SibSp + Parch)

「小象量化教研组」编著

🎁 免费学习资源

领取《小象 11GB VIP 课件资料包与大厂真题手册》

包含全套实战 Jupyter 源码、清洗后数据集、大厂高频面试真题与专属学员答疑交流群。

  • 完整 Python / 数据分析 Jupyter 实战源码
  • 大厂真实业务数据集与练习题
  • 微信扫码添加课程顾问,免费获取网盘下载链接
微信二维码:扫码添加课程顾问微信扫码添加顾问