NumPy入门:从零搭建你的量化计算引擎
说实话,做量化交易这些年,我见过太多人一上来就扑到pandas上。结果呢?数据量一大,程序直接卡死。为什么?因为底层没打好。NumPy就是那个底层——它是Python量化世界的基石。
我个人习惯把NumPy比作「瑞士军刀」。它不花哨,但每个量化交易员都离不开。今天我们就从零开始,把这把刀磨锋利。
1. NumPy数组创建:从列表到数组的蜕变
先说说最基础的东西——怎么创建一个NumPy数组。你可能会想:「不就是把列表转一下吗?」嗯,还真没那么简单。
import numpy as np
# 从列表创建
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1) # [1 2 3 4 5]
# 创建全零数组
zeros = np.zeros((3, 4))
print(zeros)
# 创建全一数组
ones = np.ones((2, 3))
# 创建等差数列
seq = np.arange(0, 10, 2) # [0 2 4 6 8]
# 创建等间隔数组
lin = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ]
我在项目中遇到过一个问题:用np.array()创建二维数组时,如果内层列表长度不一致,它会变成一维的对象数组。这坑我踩过,当时查了半天才发现是数据源有问题。
dtype 参数指定。比如 np.array([1,2,3], dtype=np.float64)。
2. 数组属性:摸清你的数据底细
拿到一个数组,第一件事是什么?我个人习惯先看它的「三围」——形状、维度、大小。
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) # (2, 3) —— 2行3列
print(arr.ndim) # 2 —— 二维数组
print(arr.size) # 6 —— 总共6个元素
print(arr.dtype) # int64 —— 数据类型
print(arr.itemsize) # 8 —— 每个元素占8字节
你想想看,在量化交易中,我们经常要处理几千只股票的历史数据。如果不知道数组的形状,后续的切片、运算全都会乱套。我记得有一次回测结果对不上,最后发现是数组维度搞反了——行和列颠倒了。
| 属性 | 含义 | 量化场景举例 |
|---|---|---|
| shape | 数组形状 | (1000, 5) 表示1000个交易日,5个字段 |
| ndim | 维度数 | 2表示二维表,3表示三维张量 |
| dtype | 数据类型 | float64适合价格数据,int64适合数量 |
3. 数组索引与切片:精准定位你的数据
索引和切片,说白了就是「怎么从数组里把想要的数据掏出来」。这和Python列表很像,但NumPy更强大。
arr = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
# 基本索引
print(arr[0, 1]) # 20 —— 第0行第1列
print(arr[2]) # [70 80 90] —— 第2行
# 切片
print(arr[:, 1]) # [20 50 80] —— 所有行的第1列
print(arr[0:2, :]) # 前两行所有列
# 花式索引
indices = [0, 2]
print(arr[indices]) # 第0行和第2行
# 布尔索引
mask = arr > 50
print(arr[mask]) # [60 70 80 90]
这里有个技巧:布尔索引在量化中特别常用。比如筛选出涨幅超过5%的股票,或者找出成交量异常的日期。我曾经用布尔索引写过一个选股策略,一行代码就搞定了复杂的条件筛选。
.copy() 方法。
4. 数组运算:量化计算的加速器
为什么NumPy快?因为它把循环放到了C语言层面执行。你写一个加法,它背后是向量化操作,比Python的for循环快几十倍。
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 算术运算
print(a + b) # [5 7 9]
print(a * b) # [4 10 18]
print(a ** 2) # [1 4 9]
# 比较运算
print(a > 2) # [False False True]
# 矩阵运算
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(A @ B) # 矩阵乘法
print(A * B) # 逐元素乘法
你想想看,在量化交易中,计算收益率、波动率、协方差矩阵,全都是数组运算。我刚开始做策略回测时,用for循环算夏普比率,跑一次要5分钟。后来改成向量化运算,3秒搞定。这就是NumPy的魅力。
5. 通用函数:数学工具箱
通用函数,简称ufunc,是NumPy对数组进行逐元素运算的函数。说白了,就是不用写循环,直接对整个数组做数学操作。
prices = np.array([100.5, 101.2, 99.8, 102.0, 100.1])
# 常用数学函数
print(np.sqrt(prices)) # 平方根
print(np.log(prices)) # 自然对数
print(np.exp(prices/100)) # 指数
print(np.abs(prices - 100)) # 绝对值
# 统计函数
print(np.mean(prices)) # 均值
print(np.std(prices)) # 标准差
print(np.max(prices)) # 最大值
print(np.min(prices)) # 最小值
# 累积运算
print(np.cumsum(prices)) # 累积和
print(np.diff(prices)) # 差分 —— 计算每日涨跌
我记得有一次做因子分析,需要计算所有股票的日收益率。用np.diff()配合np.log(),一行代码就得到了对数收益率序列。如果用手写循环,代码量至少翻5倍。
本章知识体系
下面这张图,是我梳理的NumPy入门知识结构。你可以把它当作学习地图,随时回来对照。
NumPy的内容其实就这么多。但别小看它,我见过太多人因为基础不牢,后面写策略时各种报错。花一天时间把NumPy吃透,后面能省你一个月的时间。
嗯,今天就到这里。记住:量化交易的核心是数据处理,而NumPy就是那个让你处理数据快如闪电的工具。多练、多用、多踩坑,自然就熟了。
公众号:蓝海数据掘金营,微信deep3321