numpy_demo · 向量化演示
内容:
从 quant_data 导入"拉数据"函数,拿到茅台真实日线
收盘价转成 numpy 数组
日收益率:for 循环 vs 向量化,性能对比
numpy 常用操作:切片 / 统计 / np.where 生成信号
导入与主入口
import time
import numpy as np
import pandas as pd
from quant_data import get_kline
if __name__ == "__main__":
1. 拉取真实日线
df = get_kline()
print("\n----- 最近 5 个交易日 -----")
print(df.tail(5).to_string())
print("\n共", len(df), "条数据,每一条都是从服务器实时拉下来的真实行情")
2. 收盘价 → numpy 数组
close = df["close"].to_numpy()
print("\n收盘价数组(前 5 个):", close[:5])
print("数组形状:", close.shape)
3. 日收益率:for 循环 vs 向量化
先用真实数据验证两种写法结果一致,再放大到 200 万条感受性能差距。
for 循环版本
ret_loop = []
for i in range(1, len(close)):
today_ret = (close[i] - close[i - 1]) / close[i - 1]
ret_loop.append(today_ret)
ret_loop = np.array(ret_loop)
向量化版本
ret_vec = np.diff(close) / close[:-1]
print("\n逻辑验证:两种写法结果一致:", np.allclose(ret_loop, ret_vec, equal_nan=True))
放大到 200 万条 · 性能对比
big = np.tile(close, int(2_000_000 / len(close)) + 1)
print(f"放大后的数组大小: {len(big):,} 条")
t0 = time.perf_counter()
ret_loop_big = []
for i in range(1, len(big)):
ret_loop_big.append((big[i] - big[i - 1]) / big[i - 1])
ret_loop_big = np.array(ret_loop_big)
t_loop = time.perf_counter() - t0
t0 = time.perf_counter()
ret_vec_big = np.diff(big) / big[:-1]
t_vec = time.perf_counter() - t0
print("\n----- 性能对比(同样的数学,不同的写法)-----")
print(f"for 循环 : {t_loop * 1000:8.1f} ms")
print(f"向量化 : {t_vec * 1000:8.1f} ms")
print(f"快约 {t_loop / max(t_vec, 1e-9):.0f} 倍")
4. numpy 常用操作
print("\n----- numpy 常用操作 -----")
print("最近 5 天收盘价 close[-5:]:", close[-5:])
print("全部均值 close.mean() :", round(close.mean(), 2))
print("波动 close.std() :", round(close.std(), 2))
print("最高 close.max() :", close.max())
print("最低 close.min() :", close.min())
signal = np.where(close > close.mean(), 1, 0)
print("\n信号序列(前 20 个):", signal[:20])
print("含义:1 = 收盘价高于五年均值,0 = 低于均值 —— 这就是策略信号的雏形")
核心要点速览
数组转换:df["close"].to_numpy()
向量化:np.diff(close) / close[:-1]
for 循环:一格一格算,慢但直观
性能对比:200 万条数据实测
切片:close[-5:] 取最近 5 天
统计:mean / std / max / min
信号:np.where(close > mean, 1, 0)
计时:time.perf_counter()
金句:
np.diff 一口气算出全部差值,
np.where 一行生成 0/1 信号 ——
numpy 把"数学"变成"一行代码"。
运行输出 · python .\numpy_demo.py
PS> python .\numpy_demo.py
[数据源] akshare 不可用(ProxyError),尝试 baostock...
login success!
logout success!
[数据源] baostock 获取成功,共 178 条
----- 最近 5 个交易日 -----
open high low close volume
date
2026-09-18 1262.99 1265.88 1256.10 1257.12 2489087
2026-09-21 1259.00 1259.95 1250.80 1252.57 2501689
2026-09-22 1252.15 1265.88 1248.10 1253.80 2457294
2026-09-23 1255.03 1271.50 1250.89 1251.24 3098122
2026-09-24 1250.01 1256.13 1231.05 1237.00 3123935
共 178 条数据,每一条都是从服务器实时拉下来的真实行情
收盘价数组(前 5 个): [1393.035158 1394.99869283 1390.45618688 1379.6518609 1386.2946653 ]
数组形状: (178,)
逻辑验证:两种写法结果一致: True
放大后的数组大小: 2,000,008 条
----- 性能对比(同样的数学,不同的写法)-----
for 循环 : 5130.7 ms
向量化 : 26.4 ms
快约 194 倍
----- numpy 常用操作 -----
最近 5 天收盘价 close[-5:]: [1257.12 1252.57 1253.8 1251.24 1237. ]
全部均值 close.mean() : 1326.43
波动 close.std() : 76.99
最高 close.max() : 1519.053065
最低 close.min() : 1168.63
信号序列(前 20 个): [1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1]
含义:1 = 收盘价高于五年均值,0 = 低于均值 —— 这就是策略信号的雏形
关键结论:同样的数学,向量化比 for 循环快约 194 倍(5130.7 ms → 26.4 ms)。