4、必备Python库(一):NumPy基础:数组创建、索引与切片、数学运算、随机数生成
各位同学,欢迎来到第四讲。今天咱们聊聊 NumPy。
说实话,在量化交易这个行当里,NumPy 就是你的左膀右臂。我做了这么多年策略开发,几乎每天都要跟它打交道。你想想看,处理行情数据、计算收益率、做回测,哪一步离得开数组运算?
这一讲,我带你快速掌握 NumPy 最核心的四个技能:数组创建、索引与切片、数学运算、随机数生成。别怕,都是干货,上手很快。
4.1 数组创建:从零开始造数据
先说说怎么创建数组。我个人习惯,写策略前第一件事就是先把数据装进 NumPy 数组里。
最基础的方法:
import numpy as np
# 从列表创建
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1) # [1 2 3 4 5]
# 二维数组(矩阵)
arr2 = np.array([[1, 2], [3, 4]])
print(arr2)
# [[1 2]
# [3 4]]
嗯,这里要注意:传入的数据类型要一致。如果混了字符串和数字,NumPy 会全部转成字符串。我在项目中遇到过这种情况,回测时算收益率突然报错,查了半天才发现是数据类型搞混了。
快速生成特殊数组:
# 全零数组
zeros = np.zeros((3, 4)) # 3行4列,全是0
# 全一数组
ones = np.ones((2, 3)) # 2行3列,全是1
# 单位矩阵
eye = np.eye(4) # 4x4 单位矩阵
# 等差数列
arange_arr = np.arange(0, 10, 2) # [0 2 4 6 8]
# 等间隔数列
linspace_arr = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ]
np.zeros() 来预分配持仓数组,这样比动态追加快得多。你想想看,几百万条数据,用 Python 列表一个个 append,那速度简直没法看。
4.2 索引与切片:精准定位你的数据
说白了,索引就是找数据的位置。NumPy 的索引比 Python 列表强大得多。
一维数组索引:
arr = np.array([10, 20, 30, 40, 50])
print(arr[0]) # 10
print(arr[-1]) # 50
print(arr[1:4]) # [20 30 40]
二维数组索引:
matrix = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(matrix[0, 1]) # 2(第0行第1列)
print(matrix[1, :]) # [4 5 6](第1行所有列)
print(matrix[:, 2]) # [3 6 9](所有行第2列)
.copy() 方法。
我曾经在写策略时踩过这个坑:对切片做了修改,结果原数据也跟着变了,回测结果完全对不上。后来养成了习惯,需要独立数据时一定加 .copy()。
布尔索引: 这个在量化里太常用了。
prices = np.array([100, 102, 98, 105, 97])
# 找出所有大于100的价格
high_prices = prices[prices > 100]
print(high_prices) # [102 105]
你想想看,筛选涨停股、过滤异常数据,布尔索引一行代码搞定。
4.3 数学运算:让数组自己算
NumPy 最爽的地方就是向量化运算。不用写循环,数组自己就能算。
逐元素运算:
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(np.sqrt(a)) # [1. 1.41 1.73]
广播机制: 说白了,就是形状不同的数组也能做运算。
# 标量广播
arr = np.array([1, 2, 3])
print(arr + 10) # [11 12 13]
# 一维与二维广播
matrix = np.array([[1, 2, 3],
[4, 5, 6]])
row = np.array([10, 20, 30])
print(matrix + row)
# [[11 22 33]
# [14 25 36]]
.reshape() 调整形状。
统计函数: 做量化必备。
data = np.array([100, 102, 98, 105, 97])
print(np.mean(data)) # 100.4
print(np.std(data)) # 3.2
print(np.max(data)) # 105
print(np.min(data)) # 97
print(np.sum(data)) # 502
计算收益率、波动率,这些函数直接拿来用就行。
4.4 随机数生成:模拟与回测的基石
随机数在量化里用处太大了。蒙特卡洛模拟、随机策略测试、数据增强,都离不开它。
常用随机函数:
# 设置种子(保证结果可复现)
np.random.seed(42)
# 均匀分布 [0,1)
rand_arr = np.random.rand(3, 3)
# 标准正态分布
randn_arr = np.random.randn(1000)
# 整数随机
randint_arr = np.random.randint(0, 100, size=10)
# 从数组中随机选择
choices = np.random.choice([1, 2, 3, 4, 5], size=3, replace=False)
np.random.seed()。这样别人复现我的结果时,随机数序列完全一致,不会出现「你的结果和我的不一样」这种尴尬情况。
举个例子,用随机数模拟股价走势:
# 模拟100天的收益率(正态分布)
returns = np.random.randn(100) * 0.01 # 日波动率1%
# 计算累计价格
price = 100 * np.cumprod(1 + returns)
print(price[:5]) # 前5天的价格
嗯,这个例子虽然简单,但蒙特卡洛模拟的核心思想就在里面了。
4.5 实战小练习:计算移动平均线
光说不练假把式。咱们用 NumPy 实现一个简单的 5 日移动平均线。
prices = np.array([100, 102, 101, 105, 103, 107, 106])
# 方法1:手动计算
ma5_manual = np.array([
np.mean(prices[i:i+5]) for i in range(len(prices)-4)
])
print(ma5_manual) # [102.2 103.6 104.4]
# 方法2:用卷积(更高效)
ma5_conv = np.convolve(prices, np.ones(5)/5, mode='valid')
print(ma5_conv) # [102.2 103.6 104.4]
你看,用 np.convolve 一行代码就搞定了。我在实盘策略里就是这么写的,速度比循环快几十倍。
好了,这一讲的内容就到这里。NumPy 的基础操作你基本都掌握了。记住:数组创建是起点,索引切片是工具,数学运算是核心,随机数是武器。把这四个点练熟,后面的 Pandas 和回测框架学起来会轻松很多。
有什么问题,欢迎随时交流。咱们下节课见。