人工智能之数据分析 numpy
第十五章 项目实践
@
目录
- [人工智能之数据分析 numpy](#人工智能之数据分析 numpy)
- 前言
- [🧪 项目 1:图像灰度化与边缘检测(基础)](#🧪 项目 1:图像灰度化与边缘检测(基础))
- [📊 项目 2:股票收益率分析(统计与金融)](#📊 项目 2:股票收益率分析(统计与金融))
- [🌐 项目 3:地理距离矩阵计算(广播与向量化)](#🌐 项目 3:地理距离矩阵计算(广播与向量化))
- [🔢 项目 4:主成分分析(PCA)从零实现](#🔢 项目 4:主成分分析(PCA)从零实现)
- [⚡ 项目 5:性能对比 ------ 循环 vs 向量化 vs Numba](#⚡ 项目 5:性能对比 —— 循环 vs 向量化 vs Numba)
- [📚 学习建议](#📚 学习建议)
- [🔚 总结](#🔚 总结)
- 后续
- 资料关注
前言
本文 5 个由浅入深的 NumPy 项目练习,覆盖数组操作、数学计算、数据处理、可视化和性能优化,适合巩固知识并提升实战能力。其中部分项目涉及到后续教程的学习内容,可以根据相关领域去拓展,或者学习完后续在进行复现。
🧪 项目 1:图像灰度化与边缘检测(基础)
目标
用纯 NumPy 实现彩色图像转灰度图,并进行简单边缘检测(Sobel 算子)。
知识点
- 数组切片与广播
- 卷积(手动实现)
- 图像作为 3D 数组(H×W×C)
步骤
python
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
# 1. 加载图像(可用任意本地图片或生成模拟数据)
# 若无图片,用随机数组模拟:
img = np.random.randint(0, 256, (200, 200, 3), dtype=np.uint8)
# 2. 转灰度(加权平均:R*0.299 + G*0.587 + B*0.114)
gray = np.dot(img[...,:3], [0.299, 0.587, 0.114]).astype(np.uint8)
# 3. Sobel 边缘检测(手动卷积)
def sobel_edge(gray):
# Sobel 核
Kx = np.array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]])
Ky = np.array([[-1,-2,-1],
[ 0, 0, 0],
[ 1, 2, 1]])
h, w = gray.shape
edges = np.zeros_like(gray, dtype=np.float32)
# 手动卷积(忽略边界)
for i in range(1, h-1):
for j in range(1, w-1):
gx = np.sum(Kx * gray[i-1:i+2, j-1:j+2])
gy = np.sum(Ky * gray[i-1:i+2, j-1:j+2])
edges[i, j] = np.sqrt(gx**2 + gy**2)
return edges.astype(np.uint8)
edges = sobel_edge(gray)
# 4. 可视化
fig, axs = plt.subplots(1, 3, figsize=(12, 4))
axs[0].imshow(img)
axs[0].set_title('Original')
axs[1].imshow(gray, cmap='gray')
axs[1].set_title('Grayscale')
axs[2].imshow(edges, cmap='gray')
axs[2].set_title('Edges')
plt.show()
✅ 进阶挑战 :用
np.lib.stride_tricks.sliding_window_view实现无循环卷积,大幅提升速度!
📊 项目 2:股票收益率分析(统计与金融)
目标
模拟股票价格,计算日收益率、波动率、最大回撤等指标。
知识点
- 随机游走模拟
- 百分比变化
np.diff/np.log - 统计函数(std, max, argmin)
- 布尔索引
步骤
python
import numpy as np
import matplotlib.pyplot as plt
# 1. 模拟股价(几何布朗运动简化版)
np.random.seed(42)
n_days = 252 # 一年交易日
returns = np.random.normal(loc=0.001, scale=0.02, size=n_days) # 日收益率
price = 100 * np.exp(np.cumsum(returns)) # 初始价100
# 2. 计算关键指标
daily_returns = np.diff(price) / price[:-1] # 或直接用 returns
volatility = np.std(daily_returns) * np.sqrt(252) # 年化波动率
max_drawdown = np.min(price / np.maximum.accumulate(price) - 1)
print(f"年化波动率: {volatility:.2%}")
print(f"最大回撤: {max_drawdown:.2%}")
# 3. 绘制价格与回撤曲线
peak = np.maximum.accumulate(price)
drawdown = (price - peak) / peak
fig, ax1 = plt.subplots(figsize=(10, 6))
ax1.plot(price, 'b-', label='Price')
ax1.set_ylabel('Price', color='b')
ax2 = ax1.twinx()
ax2.fill_between(range(len(drawdown)), drawdown, 0, color='r', alpha=0.3, label='Drawdown')
ax2.set_ylabel('Drawdown', color='r')
plt.title('Stock Price & Drawdown')
plt.show()
✅ 扩展:加入多只股票,计算协方差矩阵和投资组合风险。
🌐 项目 3:地理距离矩阵计算(广播与向量化)
目标
给定多个城市的经纬度,计算所有城市对之间的球面距离(Haversine 公式)。
知识点
- 广播机制
- 三角函数
- 向量化替代嵌套循环
步骤
python
import numpy as np
# 1. 城市数据(经度, 纬度)单位:度
cities = np.array([
[116.4, 39.9], # 北京
[121.5, 31.2], # 上海
[113.3, 23.1], # 广州
[106.5, 29.6] # 重庆
])
# 转为弧度
lat = np.radians(cities[:, 1])
lon = np.radians(cities[:, 0])
# 2. 使用广播计算所有配对
lat1 = lat[:, np.newaxis] # (4,1)
lat2 = lat[np.newaxis, :] # (1,4)
lon1 = lon[:, np.newaxis]
lon2 = lon[np.newaxis, :]
# Haversine 公式
dlat = lat2 - lat1
dlon = lon2 - lon1
a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1-a))
distance_km = 6371 * c # 地球半径 ≈ 6371 km
# 3. 输出距离矩阵
city_names = ['Beijing', 'Shanghai', 'Guangzhou', 'Chongqing']
print("Distance Matrix (km):")
print(f"{'':<12}" + "".join(f"{name:<12}" for name in city_names))
for i, name in enumerate(city_names):
row = "".join(f"{distance_km[i,j]:<12.1f}" for j in range(len(city_names)))
print(f"{name:<12}{row}")
✅ 优势:无循环,O(1) 内存扩展(相比 O(n²) 循环)
🔢 项目 4:主成分分析(PCA)从零实现
目标
不用 sklearn,仅用 NumPy 实现 PCA,用于降维。
知识点
- 中心化
- 协方差矩阵
- 特征值分解
- 投影
步骤
python
import numpy as np
import matplotlib.pyplot as plt
# 1. 生成模拟数据(2D)
np.random.seed(0)
X = np.random.randn(100, 2) @ np.array([[2, 1], [1, 1]]) # 相关数据
# 2. PCA 实现
def pca(X, n_components=2):
# 中心化
X_centered = X - X.mean(axis=0)
# 协方差矩阵
cov = np.cov(X_centered.T) # 注意:np.cov 默认按行是变量
# 特征分解
eigenvals, eigenvecs = np.linalg.eigh(cov) # 对称矩阵用 eigh 更稳定
# 按特征值降序排序
idx = np.argsort(eigenvals)[::-1]
components = eigenvecs[:, idx[:n_components]]
# 投影
X_pca = X_centered @ components
return X_pca, components, eigenvals[idx]
X_pca, comps, vals = pca(X, n_components=2)
# 3. 可视化
plt.figure(figsize=(8, 4))
plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], alpha=0.7)
plt.title('Original Data')
plt.subplot(1, 2, 2)
plt.scatter(X_pca[:, 0], X_pca[:, 1], alpha=0.7, c='red')
plt.title('PCA Transformed')
plt.axhline(0, color='k', linewidth=0.5)
plt.axvline(0, color='k', linewidth=0.5)
plt.show()
print("Explained variance ratio:", vals / vals.sum())
✅ 理解核心:PCA = 数据旋转到方差最大方向。
⚡ 项目 5:性能对比 ------ 循环 vs 向量化 vs Numba
目标
对比三种方式计算两个大数组的欧氏距离效率。
知识点
- 性能分析(
time.time()) - 向量化优势
- 可选:Numba JIT 加速
步骤
python
import numpy as np
import time
# 数据
N = 1000000
a = np.random.rand(N, 3)
b = np.random.rand(N, 3)
# 方法1:Python 循环(慢)
def euclidean_loop(a, b):
dists = []
for i in range(len(a)):
d = np.sqrt((a[i,0]-b[i,0])**2 + (a[i,1]-b[i,1])**2 + (a[i,2]-b[i,2])**2)
dists.append(d)
return np.array(dists)
# 方法2:NumPy 向量化(快)
def euclidean_vectorized(a, b):
return np.sqrt(np.sum((a - b)**2, axis=1))
# 方法3:使用 scipy.spatial.distance(可选)
# from scipy.spatial.distance import cdist
# dists = np.diag(cdist(a, b))
# 测试
start = time.time()
# dist1 = euclidean_loop(a, b) # 跳过,太慢!
# print("Loop time:", time.time() - start)
start = time.time()
dist2 = euclidean_vectorized(a, b)
print("Vectorized time:", time.time() - start)
# 验证结果一致
# print("Max diff:", np.max(np.abs(dist1 - dist2)))
💡 典型结果:向量化比循环快 100~1000 倍!
✅ 扩展 :尝试用@numba.jit加速循环版本,看能否接近向量化性能。
📚 学习建议
| 项目 | 推荐顺序 | 巩固知识点 |
|---|---|---|
| 1. 图像处理 | 1 | 广播、切片、基础数学 |
| 2. 金融统计 | 2 | 随机数、统计函数、累积操作 |
| 3. 地理距离 | 3 | 广播高级应用 |
| 4. PCA | 4 | 线性代数、特征分解 |
| 5. 性能对比 | 5 | 向量化思想、性能意识 |
🔚 总结
这些项目覆盖了 NumPy 的核心能力:
- 数组作为通用容器
- 向量化替代循环
- 广播实现高效计算
- 与 Matplotlib 无缝可视化
- 为机器学习/科学计算奠基
💡 下一步:将这些技能迁移到 Pandas(表格)、SciPy(高级算法)、scikit-learn(ML)中。
后续
本文主要针对numpy相关的由浅入深的一个项目实践。之前的python过渡项目部分代码已经上传至gitee,后续会逐步更新,主要受时间原因限制,当然自己也可以克隆到本地学习拓展。
资料关注
公众号:咚咚王
gitee:https://gitee.com/wy18585051844/ai_learning
《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》