向量化最佳实践
1. 尽量使用NumPy内置函数而非Python循环
2. 利用广播机制避免显式循环
3. 使用向量化条件替换if-else
4. 注意内存布局,优先使用连续数组
5. 合理使用视图而非拷贝
Python数据处理基础
NumPy是Python科学计算的基础库,提供了强大的数组操作和向量化计算能力。 在量化交易中,向量化计算可以显著提升处理大量金融数据的性能。 本节将系统介绍NumPy的核心概念和向量化计算技巧。
import numpy as np
# 从列表创建
arr = np.array([1, 2, 3, 4, 5])
# 创建全零数组
zeros = np.zeros((5, 3)) # 5行3列的全零矩阵
# 创建全一数组
ones = np.ones((3, 3))
# 创建指定范围数组
range_arr = np.arange(10) # 0-9
linspace = np.linspace(0, 10, 11) # 0-10, 分成11个点
# 创建随机数组
random_arr = np.random.rand(3, 3) # 均匀分布
normal_arr = np.random.randn(3, 3) # 标准正态分布
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) # 数组形状 (2, 3)
print(arr.ndim) # 维度数 2
print(arr.dtype) # 数据类型 int64
print(arr.size) # 元素总数 6
print(arr.itemsize) # 每个元素字节大小 8
print(arr.nbytes) # 总字节大小 48
# 使用循环计算
import time
def sum_loop(n):
total = 0
for i in range(n):
total += i * 2
return total
# 使用向量化计算
def sum_vectorized(n):
arr = np.arange(n)
return np.sum(arr * 2)
# 性能测试
start = time.time()
sum_loop(10_000_000)
loop_time = time.time() - start
start = time.time()
sum_vectorized(10_000_000)
vectorized_time = time.time() - start
print(f"循环时间: {loop_time:.4f}s")
print(f"向量化时间: {vectorized_time:.4f}s")
print(f"加速比: {loop_time/vectorizedized:.2f}x")
# 价格数据向量化处理
prices = np.array([10.5, 11.2, 10.8, 11.5, 10.9])
# 计算收益率
returns = np.diff(prices) / prices[:-1]
# 计算移动平均
window = 3
ma = np.convolve(prices, np.ones(window)/window, mode='valid')
# 计算标准差
std = np.std(prices)
# 条件过滤
high_prices = prices[prices > 11]
# 多条件
filtered = prices[(prices > 10.5) & (prices < 11.5)]
arr = np.array([1, 2, 3, 4, 5])
# 基本运算
arr + 2 # 加法
arr * 2 # 乘法
arr ** 2 # 幂运算
np.sqrt(arr) # 开方
np.exp(arr) # 指数
np.log(arr) # 对数
# 聚合运算
np.sum(arr) # 求和
np.mean(arr) # 平均值
np.std(arr) # 标准差
np.median(arr) # 中位数
np.min(arr) # 最小值
np.max(arr) # 最大值
np.percentile(arr, 95) # 95分位数
# 逐对运算
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
np.add(arr1, arr2) # 逐元素相加
np.multiply(arr1, arr2) # 逐元素相乘
np.dot(arr1, arr2) # 点积
# 计算组合收益率
weights = np.array([0.3, 0.4, 0.3])
returns = np.array([0.05, 0.08, 0.06])
# 组合收益率
portfolio_return = np.dot(weights, returns)
# 计算年化波动率
daily_returns = np.random.randn(252) * 0.02
annual_vol = np.std(daily_returns) * np.sqrt(252)
# 计算夏普比率
risk_free_rate = 0.03
sharpe_ratio = (portfolio_return - risk_free_rate) / annual_vol
# 不同形状数组运算
arr1 = np.array([[1, 2, 3], [4, 5, 6]]) # (2, 3)
arr2 = np.array([10, 20, 30]) # (3,)
# 自动广播
result = arr1 + arr2 # (2, 3)
# 常用场景:标准化
data = np.random.randn(100, 5)
mean = np.mean(data, axis=0) # (5,)
std = np.std(data, axis=0) # (5,)
normalized = (data - mean) / std # (100, 5)
# 矩阵相加(列方向)
matrix = np.array([[1, 2], [3, 4], [5, 6]]) # (3, 2)
vector = np.array([10, 20]) # (2,)
result = matrix + vector # (3, 2)
1. 尽量使用NumPy内置函数而非Python循环
2. 利用广播机制避免显式循环
3. 使用向量化条件替换if-else
4. 注意内存布局,优先使用连续数组
5. 合理使用视图而非拷贝