【Python进阶学习】-NumPy详细介绍指南(附demo)

NumPy:Python科学计算的基石

目录

章节 核心内容
[一、NumPy是什么?](#章节 核心内容 一、NumPy是什么? 专业定义与核心定位 二、专业术语深度解析 核心技术概念详解 三、NumPy的核心数据结构 数组与矩阵详解 四、大白话解释:它到底做什么? 通俗易懂的比喻说明 五、生活案例:实际应用场景 各行各业的应用实例 六、NumPy与其他库的关系 Python生态中的位置 七、实战演示:从零开始使用NumPy 完整代码示例 八、常见问题与解决方案 新手常见问题 九、总结与学习路径 如何系统学习NumPy) 专业定义与核心定位
[二、专业术语深度解析](#章节 核心内容 一、NumPy是什么? 专业定义与核心定位 二、专业术语深度解析 核心技术概念详解 三、NumPy的核心数据结构 数组与矩阵详解 四、大白话解释:它到底做什么? 通俗易懂的比喻说明 五、生活案例:实际应用场景 各行各业的应用实例 六、NumPy与其他库的关系 Python生态中的位置 七、实战演示:从零开始使用NumPy 完整代码示例 八、常见问题与解决方案 新手常见问题 九、总结与学习路径 如何系统学习NumPy) 核心技术概念详解
[三、NumPy的核心数据结构](#章节 核心内容 一、NumPy是什么? 专业定义与核心定位 二、专业术语深度解析 核心技术概念详解 三、NumPy的核心数据结构 数组与矩阵详解 四、大白话解释:它到底做什么? 通俗易懂的比喻说明 五、生活案例:实际应用场景 各行各业的应用实例 六、NumPy与其他库的关系 Python生态中的位置 七、实战演示:从零开始使用NumPy 完整代码示例 八、常见问题与解决方案 新手常见问题 九、总结与学习路径 如何系统学习NumPy) 数组与矩阵详解
[四、大白话解释:它到底做什么?](#章节 核心内容 一、NumPy是什么? 专业定义与核心定位 二、专业术语深度解析 核心技术概念详解 三、NumPy的核心数据结构 数组与矩阵详解 四、大白话解释:它到底做什么? 通俗易懂的比喻说明 五、生活案例:实际应用场景 各行各业的应用实例 六、NumPy与其他库的关系 Python生态中的位置 七、实战演示:从零开始使用NumPy 完整代码示例 八、常见问题与解决方案 新手常见问题 九、总结与学习路径 如何系统学习NumPy) 通俗易懂的比喻说明
[五、生活案例:实际应用场景](#章节 核心内容 一、NumPy是什么? 专业定义与核心定位 二、专业术语深度解析 核心技术概念详解 三、NumPy的核心数据结构 数组与矩阵详解 四、大白话解释:它到底做什么? 通俗易懂的比喻说明 五、生活案例:实际应用场景 各行各业的应用实例 六、NumPy与其他库的关系 Python生态中的位置 七、实战演示:从零开始使用NumPy 完整代码示例 八、常见问题与解决方案 新手常见问题 九、总结与学习路径 如何系统学习NumPy) 各行各业的应用实例
[六、NumPy与其他库的关系](#章节 核心内容 一、NumPy是什么? 专业定义与核心定位 二、专业术语深度解析 核心技术概念详解 三、NumPy的核心数据结构 数组与矩阵详解 四、大白话解释:它到底做什么? 通俗易懂的比喻说明 五、生活案例:实际应用场景 各行各业的应用实例 六、NumPy与其他库的关系 Python生态中的位置 七、实战演示:从零开始使用NumPy 完整代码示例 八、常见问题与解决方案 新手常见问题 九、总结与学习路径 如何系统学习NumPy) Python生态中的位置
[七、实战演示:从零开始使用NumPy](#章节 核心内容 一、NumPy是什么? 专业定义与核心定位 二、专业术语深度解析 核心技术概念详解 三、NumPy的核心数据结构 数组与矩阵详解 四、大白话解释:它到底做什么? 通俗易懂的比喻说明 五、生活案例:实际应用场景 各行各业的应用实例 六、NumPy与其他库的关系 Python生态中的位置 七、实战演示:从零开始使用NumPy 完整代码示例 八、常见问题与解决方案 新手常见问题 九、总结与学习路径 如何系统学习NumPy) 完整代码示例
[八、常见问题与解决方案](#章节 核心内容 一、NumPy是什么? 专业定义与核心定位 二、专业术语深度解析 核心技术概念详解 三、NumPy的核心数据结构 数组与矩阵详解 四、大白话解释:它到底做什么? 通俗易懂的比喻说明 五、生活案例:实际应用场景 各行各业的应用实例 六、NumPy与其他库的关系 Python生态中的位置 七、实战演示:从零开始使用NumPy 完整代码示例 八、常见问题与解决方案 新手常见问题 九、总结与学习路径 如何系统学习NumPy) 新手常见问题
[九、总结与学习路径](#章节 核心内容 一、NumPy是什么? 专业定义与核心定位 二、专业术语深度解析 核心技术概念详解 三、NumPy的核心数据结构 数组与矩阵详解 四、大白话解释:它到底做什么? 通俗易懂的比喻说明 五、生活案例:实际应用场景 各行各业的应用实例 六、NumPy与其他库的关系 Python生态中的位置 七、实战演示:从零开始使用NumPy 完整代码示例 八、常见问题与解决方案 新手常见问题 九、总结与学习路径 如何系统学习NumPy) 如何系统学习NumPy

一、NumPy是什么?

1.1 官方定义

NumPy(Numerical Python) 是Python科学计算的基础库,提供了高性能的多维数组对象(ndarray)以及用于操作这些数组的工具。它是几乎所有Python科学计算和数据分析库(如Pandas、SciPy、Scikit-learn、TensorFlow等)的底层依赖。

1.2 一句话概括

"Python中的'数学计算加速器'和'数据处理工厂'"

就像Excel是表格处理的标杆一样,NumPy是Python中数值计算的标杆。

1.3 核心功能概览

复制代码
输入:各种数值数据
处理:NumPy数组和函数
输出:高效的数学运算结果

主要功能:
1. 多维数组(ndarray):高效的存储和操作
2. 数学函数:线性代数、傅里叶变换、随机数生成
3. 广播机制:不同形状数组的智能运算
4. 内存优化:比Python列表更节省内存
5. 速度优势:比纯Python快10-100倍

二、专业术语深度解析

2.1 核心技术概念

术语 专业解释 重要性
ndarray N-dimensional array,多维数组,NumPy的核心数据结构 所有运算的基础
dtype 数据类型,如int32, float64, complex128等 决定精度和内存占用
shape 数组的形状,如(3,4)表示3行4列的二维数组 描述数组维度
strides 步长,数组在内存中的寻址方式 影响数组操作效率
broadcasting 广播机制,允许不同形状数组进行运算 实现数组智能运算
ufunc 通用函数,对数组进行元素级运算的函数 实现向量化运算
view 视图,与原数组共享数据,但不拥有数据 节省内存,提高效率

2.2 NumPy的底层原理

为什么NumPy这么快?

python 复制代码
# Python列表 vs NumPy数组

# Python列表:每个元素都是独立对象
python_list = [1, 2, 3, 4, 5]
# 内存:存储5个独立对象 + 类型信息 + 引用

# NumPy数组:连续内存块,单一数据类型
import numpy as np
numpy_array = np.array([1, 2, 3, 4, 5], dtype=np.int32)
# 内存:连续存储5个int32(4字节×5=20字节)

# 运算速度对比
import time

# Python列表求和
start = time.time()
sum_python = sum([i for i in range(1000000)])
print(f"Python列表求和: {time.time()-start:.6f}秒")

# NumPy数组求和
start = time.time()
sum_numpy = np.arange(1000000).sum()
print(f"NumPy数组求和: {time.time()-start:.6f}秒")

# 结果:NumPy通常快10-100倍

内存布局对比

复制代码
Python列表:
[元素1对象] → [int对象, 值=1, 类型=int]
[元素2对象] → [int对象, 值=2, 类型=int]
...(每个元素都是独立对象)

NumPy数组:
[内存块] → | 1 | 2 | 3 | 4 | 5 |(连续存储,单一类型)

三、NumPy的核心数据结构

3.1 ndarray:多维数组

创建数组的不同方式

python 复制代码
import numpy as np

# 1. 从Python列表创建
arr1 = np.array([1, 2, 3, 4, 5])  # 一维数组
arr2 = np.array([[1, 2, 3], [4, 5, 6]])  # 二维数组

# 2. 特殊数组创建
zeros = np.zeros((3, 4))  # 3行4列的全0数组
ones = np.ones((2, 3, 4))  # 2个3行4列的全1数组(三维)
full = np.full((2, 2), 7)  # 2行2列的全7数组
identity = np.eye(3)  # 3×3的单位矩阵

# 3. 序列数组
range_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.]

# 4. 随机数组
random_arr = np.random.rand(3, 3)  # 3×3的随机数组(0-1)
normal_arr = np.random.randn(2, 2)  # 2×2的正态分布随机数组

3.2 数组属性详解

python 复制代码
# 创建一个示例数组
arr = np.array([[1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]])

print("数组形状(shape):", arr.shape)  # (3, 4) → 3行4列
print("数组维度(ndim):", arr.ndim)    # 2 → 二维数组
print("数组大小(size):", arr.size)    # 12 → 总元素个数
print("数据类型(dtype):", arr.dtype)  # int64 → 64位整数
print("每个元素字节数(itemsize):", arr.itemsize)  # 8 → 每个int64占8字节
print("总内存占用(nbytes):", arr.nbytes)  # 96 → 12元素×8字节=96字节
print("步长(strides):", arr.strides)  # (32, 8) → 行步长32字节,列步长8字节

3.3 数组索引与切片

python 复制代码
# 索引和切片操作
arr = np.array([[1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]])

# 1. 基础索引
print(arr[0, 1])      # 第0行第1列 → 2
print(arr[2])         # 第2行 → [9, 10, 11, 12]
print(arr[:, 1])      # 第1列 → [2, 6, 10]

# 2. 切片操作(与Python列表类似,但更强大)
print(arr[:2, 1:3])   # 前2行,第1到2列 → [[2, 3], [6, 7]]
print(arr[::2, ::2])  # 每隔一行,每隔一列 → [[1, 3], [9, 11]]

# 3. 布尔索引
mask = arr > 5
print(mask)           # 布尔掩码
print(arr[mask])      # 所有大于5的元素 → [6, 7, 8, 9, 10, 11, 12]

# 4. 花式索引(Fancy indexing)
rows = [0, 2]
cols = [1, 3]
print(arr[rows, cols])  # 第0行第1列和第2行第3列 → [2, 12]

3.4 广播机制(Broadcasting)

广播规则

  1. 如果两个数组维度不同,将维度较小的数组形状前面补1
  2. 如果两个数组在某个维度上大小相同或其中一个为1,则可以广播
  3. 如果两个数组在所有维度上都满足广播条件,则可以运算
python 复制代码
# 广播示例
A = np.array([[1, 2, 3],
              [4, 5, 6]])  # 形状:(2, 3)

B = np.array([10, 20, 30])  # 形状:(3,) → 广播为(1, 3) → (2, 3)

result = A + B
"""
计算过程:
A: [[1, 2, 3],   B: [[10, 20, 30],   结果: [[11, 22, 33],
     [4, 5, 6]]        [10, 20, 30]]         [14, 25, 36]]
"""
print(result)

# 更复杂的广播
C = np.array([[[1], [2], [3]]])  # 形状:(1, 3, 1)
D = np.array([10, 20, 30])       # 形状:(3,) → (1, 3, 1) → (1, 3, 3)
E = np.array([[100], [200]])     # 形状:(2, 1) → (2, 3, 1)

# 最终可以广播为形状(2, 3, 3)进行计算

四、大白话解释:它到底做什么?

4.1 核心比喻

NumPy就像一个"数学计算工厂"

复制代码
传统Python计算(不用NumPy):
就像手工作坊
- 每个计算都要手工处理
- 速度慢,容易出错
- 处理大量数据时效率低下

使用NumPy后:
就像现代化工厂
- 流水线批量处理数据
- 速度快,精度高
- 可以处理海量数据

4.2 具体好处

  1. "批量处理,而不是一个一个算"

    python 复制代码
    # 不用NumPy:循环处理
    prices = [100, 200, 300, 400, 500]
    discounted_prices = []
    for price in prices:
        discounted_prices.append(price * 0.8)  # 打8折
    
    # 使用NumPy:向量化处理
    import numpy as np
    prices = np.array([100, 200, 300, 400, 500])
    discounted_prices = prices * 0.8  # 一行搞定!
  2. "内存更省,计算更快"

    • Python列表:100万个数字占用约28MB内存
    • NumPy数组:100万个数字占用约8MB内存(int64)或4MB内存(int32)
    • 计算速度:NumPy比纯Python循环快10-100倍
  3. "数学运算应有尽有"

    • 加减乘除、矩阵运算、统计计算
    • 傅里叶变换、线性代数、随机数生成
    • 图像处理、信号处理、科学计算

4.3 与Python列表的区别

方面 Python列表 NumPy数组
数据类型 可以混合类型(数字、字符串、对象) 必须同一种类型
内存使用 每个元素都是独立对象,内存开销大 连续内存块,内存效率高
运算速度 循环处理,速度慢 向量化运算,速度快
功能丰富度 基本列表操作 丰富的数学函数库
使用场景 通用数据存储 科学计算和数值分析

五、生活案例:实际应用场景

5.1 学生成绩分析系统

场景:学校需要分析全年级学生的成绩

python 复制代码
import numpy as np

# 模拟1000名学生的5门课成绩(0-100分)
np.random.seed(42)  # 设置随机种子,确保结果可重复
num_students = 1000
scores = np.random.randint(0, 101, size=(num_students, 5))  # 1000×5的数组

print("成绩数组形状:", scores.shape)  # (1000, 5)

# 1. 计算每门课的平均分
subject_means = scores.mean(axis=0)  # 按列求平均
print("各科目平均分:", subject_means)

# 2. 计算每个学生的平均分
student_means = scores.mean(axis=1)  # 按行求平均
print("前10名学生平均分:", student_means[:10])

# 3. 找出每门课的最高分和最低分
max_scores = scores.max(axis=0)
min_scores = scores.min(axis=0)
print("各科目最高分:", max_scores)
print("各科目最低分:", min_scores)

# 4. 统计各分数段人数
# 计算每个学生的总分
total_scores = scores.sum(axis=1)

# 分数段统计
bins = [0, 300, 350, 400, 450, 500]  # 总分500分
hist, _ = np.histogram(total_scores, bins=bins)
print("分数段人数分布:", hist)
print("分数段:", ["0-300", "301-350", "351-400", "401-450", "451-500"])

# 5. 找出优秀学生(平均分≥90)
excellent_mask = student_means >= 90
excellent_students = scores[excellent_mask]
print(f"优秀学生人数: {excellent_students.shape[0]}")

NumPy的优势体现

  • 传统方法:需要多层循环,代码复杂,速度慢
  • NumPy方法:几行代码搞定,速度快,可读性好

5.2 电商销售数据分析

场景:分析某电商平台一个月的销售数据

python 复制代码
import numpy as np

# 模拟数据:30天,4种商品,每个商品有销售额和销售量
days = 30
products = 4

# 销售额(单位:万元)
revenue = np.random.uniform(10, 100, size=(days, products))

# 销售量(单位:千件)
quantity = np.random.randint(100, 1000, size=(days, products))

print("30天销售数据分析")
print("=" * 50)

# 1. 计算每日总销售额
daily_total_revenue = revenue.sum(axis=1)
print("每日总销售额(万元):", daily_total_revenue.round(2))

# 2. 计算每种商品的平均单价
# 平均单价 = 总销售额 / 总销售量
total_revenue_per_product = revenue.sum(axis=0)
total_quantity_per_product = quantity.sum(axis=0)
avg_price_per_product = total_revenue_per_product / total_quantity_per_product
print("各商品平均单价(元/件):", (avg_price_per_product * 10000).round(2))

# 3. 找出销售最好的3天
best_days_indices = daily_total_revenue.argsort()[-3:][::-1]
print("销售额最高的3天(索引):", best_days_indices)
print("对应的销售额(万元):", daily_total_revenue[best_days_indices].round(2))

# 4. 计算每周数据(假设30天分成4周多2天)
weekly_revenue = daily_total_revenue[:28].reshape(4, 7).sum(axis=1)
print("每周销售额(万元):", weekly_revenue.round(2))

# 5. 计算环比增长率
growth_rate = np.diff(weekly_revenue) / weekly_revenue[:-1] * 100
print("周环比增长率(%):", growth_rate.round(2))

# 6. 相关性分析:销售额和星期几的关系
# 假设数据从周一开始
weekdays = np.array(['周一', '周二', '周三', '周四', '周五', '周六', '周日'])
weekday_indices = np.tile(np.arange(7), 5)[:days]  # 重复7天模式

# 计算每个星期几的平均销售额
for i in range(7):
    mask = weekday_indices == i
    avg = daily_total_revenue[mask].mean()
    print(f"{weekdays[i]}平均销售额: {avg:.2f}万元")

5.3 图像处理基础

场景:用NumPy处理图片(图片本质上是三维数组)

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 创建一个简单的图像(200×300像素,RGB三通道)
height, width = 200, 300
channels = 3

# 方法1:创建纯色图像
# 红色图像
red_image = np.zeros((height, width, channels), dtype=np.uint8)
red_image[:, :, 0] = 255  # R通道设为255

# 绿色图像
green_image = np.zeros((height, width, channels), dtype=np.uint8)
green_image[:, :, 1] = 255  # G通道设为255

# 蓝色图像
blue_image = np.zeros((height, width, channels), dtype=np.uint8)
blue_image[:, :, 2] = 255  # B通道设为255

# 方法2:创建渐变图像
gradient_image = np.zeros((height, width, channels), dtype=np.uint8)

# 创建水平渐变(红色从左到右渐变)
for x in range(width):
    gradient_image[:, x, 0] = int(255 * x / width)

# 创建垂直渐变(绿色从上到下渐变)
for y in range(height):
    gradient_image[y, :, 1] = int(255 * y / height)

# 图像处理操作
# 1. 调整亮度(所有像素值乘以系数)
brightened = np.clip(gradient_image * 1.5, 0, 255).astype(np.uint8)

# 2. 转换为灰度图
# 灰度公式:0.299*R + 0.587*G + 0.114*B
gray_image = np.dot(gradient_image[..., :3], [0.299, 0.587, 0.114]).astype(np.uint8)

# 3. 图像翻转
flipped_horizontal = gradient_image[:, ::-1, :]  # 水平翻转
flipped_vertical = gradient_image[::-1, :, :]    # 垂直翻转

# 4. 裁剪图像
cropped = gradient_image[50:150, 100:200, :]  # 裁剪中间区域

print("图像处理完成!")
print(f"原图像形状: {gradient_image.shape}")
print(f"灰度图形状: {gray_image.shape}")
print(f"裁剪后形状: {cropped.shape}")

5.4 物理模拟:抛物线运动

场景:模拟物体抛射运动轨迹

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 物理参数
g = 9.8  # 重力加速度 m/s²
v0 = 50   # 初始速度 m/s
theta = np.deg2rad(45)  # 发射角度 45度

# 分解速度
v0x = v0 * np.cos(theta)  # 水平速度
v0y = v0 * np.sin(theta)  # 垂直速度

# 时间数组
t_max = 2 * v0y / g  # 总飞行时间
t = np.linspace(0, t_max, 100)  # 100个时间点

# 计算位置(使用向量化运算,避免循环)
x = v0x * t  # 水平位移
y = v0y * t - 0.5 * g * t**2  # 垂直位移

# 计算速度和加速度
vx = np.full_like(t, v0x)  # 水平速度恒定
vy = v0y - g * t  # 垂直速度变化
v = np.sqrt(vx**2 + vy**2)  # 合速度

# 计算动能和势能
mass = 1.0  # 质量 1kg
kinetic_energy = 0.5 * mass * v**2  # 动能
potential_energy = mass * g * y  # 势能
total_energy = kinetic_energy + potential_energy  # 总能量

print("抛射运动分析结果:")
print("=" * 50)
print(f"最大高度: {y.max():.2f} 米")
print(f"最大射程: {x.max():.2f} 米")
print(f"飞行时间: {t_max:.2f} 秒")
print(f"能量守恒检查:")
print(f"  初始总能量: {total_energy[0]:.2f} J")
print(f"  最终总能量: {total_energy[-1]:.2f} J")
print(f"  能量变化: {abs(total_energy[-1] - total_energy[0]):.6f} J (应接近0)")

# 找到关键点
max_height_index = np.argmax(y)
landing_index = len(t) - 1

print(f"\n关键点信息:")
print(f"  最高点 - 时间: {t[max_height_index]:.2f}s, 高度: {y[max_height_index]:.2f}m")
print(f"  落地点 - 时间: {t[landing_index]:.2f}s, 距离: {x[landing_index]:.2f}m")

六、NumPy与其他库的关系

6.1 Python科学计算生态系统

复制代码
NumPy(基础)
    ↓
Pandas(数据分析)    SciPy(科学计算)    Matplotlib(绘图)
    ↓                      ↓                    ↓
Scikit-learn(机器学习)   StatsModels(统计)   Seaborn(高级绘图)
    ↓
TensorFlow/PyTorch(深度学习)

6.2 与其他库的对比

库名 主要用途 与NumPy的关系 适用场景
Pandas 数据分析,表格处理 基于NumPy,提供DataFrame结构 数据清洗、分析、处理表格数据
SciPy 科学计算,高级数学函数 基于NumPy,提供更多数学算法 优化、积分、信号处理、图像处理
Matplotlib 数据可视化,绘图 使用NumPy数组作为数据输入 绘制图表、可视化数据
Scikit-learn 机器学习 使用NumPy数组存储特征和标签 分类、回归、聚类等机器学习任务
TensorFlow 深度学习 底层使用NumPy-like的数组 神经网络、深度学习模型

6.3 如何选择使用哪个库

python 复制代码
# 场景1:基础数值计算 → 直接用NumPy
import numpy as np
# 矩阵运算、数组操作、数学函数

# 场景2:数据分析和处理 → Pandas + NumPy
import pandas as pd
# 表格数据、时间序列、数据清洗

# 场景3:科学计算和算法 → SciPy + NumPy
from scipy import optimize, integrate, stats
# 优化问题、积分计算、统计分析

# 场景4:机器学习 → Scikit-learn + NumPy
from sklearn import linear_model, svm, ensemble
# 机器学习模型训练和预测

# 场景5:数据可视化 → Matplotlib + NumPy
import matplotlib.pyplot as plt
# 绘制各种图表

# 实际项目中,通常组合使用
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# 这就是典型的Python数据科学工作流

七、实战演示:从零开始使用NumPy

7.1 安装与基础使用

安装NumPy

bash 复制代码
# 使用pip安装
pip install numpy

# 使用conda安装(推荐用于科学计算环境)
conda install numpy

# 验证安装
python -c "import numpy; print(numpy.__version__)"

第一个NumPy程序

python 复制代码
import numpy as np

# 1. 创建数组
print("1. 创建数组示例")
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(f"一维数组: {arr1}")
print(f"二维数组:\n{arr2}")

# 2. 数组属性
print("\n2. 数组属性")
print(f"形状: {arr2.shape}")
print(f"维度: {arr2.ndim}")
print(f"大小: {arr2.size}")
print(f"数据类型: {arr2.dtype}")

# 3. 数组运算
print("\n3. 数组运算")
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(f"加法: {a + b}")
print(f"乘法: {a * b}")
print(f"点积: {np.dot(a, b)}")

# 4. 统计函数
print("\n4. 统计函数")
data = np.array([2, 5, 8, 3, 9, 4, 7, 1, 6])
print(f"平均值: {np.mean(data):.2f}")
print(f"中位数: {np.median(data)}")
print(f"标准差: {np.std(data):.2f}")
print(f"最小值: {np.min(data)},最大值: {np.max(data)}")

7.2 综合案例:股票数据分析

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 模拟股票数据:100天的开盘价、最高价、最低价、收盘价
np.random.seed(42)
days = 100

# 生成随机股价(初始价格100元)
initial_price = 100
prices = np.zeros(days)
prices[0] = initial_price

# 模拟每日价格变化(随机游走)
for i in range(1, days):
    # 每日变化:-2%到+2%之间
    change = np.random.uniform(-0.02, 0.02)
    prices[i] = prices[i-1] * (1 + change)

# 生成OHLC数据(开盘、最高、最低、收盘)
open_prices = prices * np.random.uniform(0.98, 1.02, days)
close_prices = prices * np.random.uniform(0.98, 1.02, days)
high_prices = np.maximum(open_prices, close_prices) * np.random.uniform(1.0, 1.03, days)
low_prices = np.minimum(open_prices, close_prices) * np.random.uniform(0.97, 1.0, days)

print("股票数据分析")
print("=" * 50)

# 1. 计算简单移动平均线(SMA)
def moving_average(data, window):
    """计算移动平均"""
    weights = np.ones(window) / window
    return np.convolve(data, weights, mode='valid')

sma_5 = moving_average(close_prices, 5)   # 5日均线
sma_20 = moving_average(close_prices, 20)  # 20日均线

# 2. 计算收益率
returns = np.diff(close_prices) / close_prices[:-1] * 100  # 百分比收益率
print(f"平均日收益率: {returns.mean():.2f}%")
print(f"收益率标准差(波动率): {returns.std():.2f}%")

# 3. 计算最大回撤
cumulative = (close_prices - close_prices[0]) / close_prices[0] * 100
running_max = np.maximum.accumulate(cumulative)
drawdown = cumulative - running_max
max_drawdown = drawdown.min()
max_drawdown_day = np.argmin(drawdown)
print(f"最大回撤: {max_drawdown:.2f}% (第{max_drawdown_day}天)")

# 4. 计算技术指标:RSI(相对强弱指数)
def calculate_rsi(prices, period=14):
    """计算RSI指标"""
    deltas = np.diff(prices)
    seed = deltas[:period]
    up = seed[seed >= 0].sum() / period
    down = -seed[seed < 0].sum() / period
    rs = up / down
    rsi = 100 - 100 / (1 + rs)
    
    rsi_values = np.zeros_like(prices)
    rsi_values[:period] = rsi
    
    for i in range(period, len(prices)):
        delta = deltas[i-1]
        if delta > 0:
            upval = delta
            downval = 0
        else:
            upval = 0
            downval = -delta
        
        up = (up * (period-1) + upval) / period
        down = (down * (period-1) + downval) / period
        rs = up / down
        rsi_values[i] = 100 - 100 / (1 + rs)
    
    return rsi_values

rsi = calculate_rsi(close_prices, 14)
print(f"当前RSI: {rsi[-1]:.2f}")

# 5. 交易信号
# 当短期均线上穿长期均线时,产生买入信号
buy_signals = []
sell_signals = []

# 注意:sma_5比close_prices少4个数据点,sma_20少19个数据点
for i in range(20, len(close_prices)-5):
    if sma_5[i-20] < sma_20[i-20] and sma_5[i-19] > sma_20[i-19]:
        buy_signals.append(i)
    elif sma_5[i-20] > sma_20[i-20] and sma_5[i-19] < sma_20[i-19]:
        sell_signals.append(i)

print(f"买入信号出现次数: {len(buy_signals)}")
print(f"卖出信号出现次数: {len(sell_signals)}")

# 可视化
plt.figure(figsize=(12, 8))

# 股价图
plt.subplot(3, 1, 1)
plt.plot(close_prices, label='收盘价', color='blue')
plt.plot(range(4, len(sma_5)+4), sma_5, label='5日均线', color='orange', linestyle='--')
plt.plot(range(19, len(sma_20)+19), sma_20, label='20日均线', color='green', linestyle='--')
plt.scatter(buy_signals, close_prices[buy_signals], color='red', marker='^', s=100, label='买入信号')
plt.scatter(sell_signals, close_prices[sell_signals], color='black', marker='v', s=100, label='卖出信号')
plt.title('股票价格与技术指标')
plt.legend()
plt.grid(True, alpha=0.3)

# 收益率图
plt.subplot(3, 1, 2)
plt.plot(returns, color='purple')
plt.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
plt.title('日收益率 (%)')
plt.grid(True, alpha=0.3)

# RSI图
plt.subplot(3, 1, 3)
plt.plot(rsi, color='brown')
plt.axhline(y=70, color='red', linestyle='--', alpha=0.5, label='超买线 (70)')
plt.axhline(y=30, color='green', linestyle='--', alpha=0.5, label='超卖线 (30)')
plt.title('RSI指标')
plt.legend()
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

八、常见问题与解决方案

8.1 安装问题

问题1:安装失败或版本冲突

bash 复制代码
# 解决方案:创建虚拟环境
python -m venv numpy_env
source numpy_env/bin/activate  # Linux/Mac
# 或
numpy_env\Scripts\activate  # Windows

pip install numpy

问题2:导入错误

python 复制代码
# 错误:ModuleNotFoundError: No module named 'numpy'
# 解决方案:确保已安装并正确导入
import numpy as np  # 标准导入方式

# 检查版本
print(np.__version__)

8.2 使用问题

问题1:数组形状不匹配

python 复制代码
# 错误:ValueError: operands could not be broadcast together with shapes...
A = np.array([[1, 2, 3], [4, 5, 6]])  # 形状:(2, 3)
B = np.array([1, 2])                  # 形状:(2,)

# 解决方案:调整数组形状
B_reshaped = B.reshape(2, 1)  # 改为(2, 1)形状
result = A + B_reshaped  # 现在可以广播为(2, 3)

问题2:数据类型问题

python 复制代码
# 错误:整数除以整数得到整数(Python 2风格)
arr = np.array([1, 2, 3, 4])
result = arr / 2  # 在旧版本可能得到[0, 1, 1, 2]

# 解决方案1:使用浮点数
result = arr / 2.0  # 得到[0.5, 1.0, 1.5, 2.0]

# 解决方案2:转换数据类型
arr_float = arr.astype(np.float64)
result = arr_float / 2

问题3:内存不足

python 复制代码
# 处理大型数组时可能出现内存问题
# 错误:MemoryError

# 解决方案1:使用合适的数据类型
# 默认int64,如果数值不大可以用int32
arr_small = np.array([1, 2, 3], dtype=np.int32)  # 节省一半内存

# 解决方案2:使用内存映射文件
large_array = np.memmap('large_array.dat', dtype=np.float32, mode='w+', shape=(10000, 10000))

# 解决方案3:分块处理
def process_in_chunks(data, chunk_size=1000):
    results = []
    for i in range(0, len(data), chunk_size):
        chunk = data[i:i+chunk_size]
        # 处理chunk
        results.append(chunk.mean())
    return np.array(results)

8.3 性能优化

技巧1:避免Python循环,使用向量化操作

python 复制代码
# 不好的做法:使用Python循环
result = []
for i in range(len(arr1)):
    result.append(arr1[i] + arr2[i])

# 好的做法:使用NumPy向量化操作
result = arr1 + arr2  # 快10-100倍

技巧2:使用原地操作减少内存分配

python 复制代码
# 不好的做法:创建新数组
arr = arr + 1  # 创建新数组,原数组不变

# 好的做法:原地操作
arr += 1  # 修改原数组,不创建新数组

技巧3:使用NumPy内置函数

python 复制代码
# 不好的做法:自己实现
def my_mean(arr):
    total = 0
    for x in arr:
        total += x
    return total / len(arr)

# 好的做法:使用np.mean()
mean_value = np.mean(arr)  # 使用C语言实现的优化函数

九、总结与学习路径

9.1 NumPy的核心价值总结

NumPy解决了四大问题

  1. 性能问题:比纯Python快10-100倍
  2. 内存问题:连续存储,比Python列表节省内存
  3. 功能问题:提供丰富的数学函数库
  4. 标准问题:成为Python科学计算的事实标准

9.2 学习路径建议

第一阶段:基础入门(1-2周)

python 复制代码
# 学习内容:
1. 数组创建和基本操作
2. 数组索引和切片
3. 数组运算和广播
4. 常用数学函数

第二阶段:进阶应用(2-4周)

python 复制代码
# 学习内容:
1. 数组形状操作(reshape, transpose等)
2. 高级索引(花式索引、布尔索引)
3. 线性代数运算
4. 随机数生成
5. 文件I/O(保存和加载数组)

第三阶段:实战应用(1-2个月)

python 复制代码
# 学习内容:
1. 与Pandas、Matplotlib等库配合使用
2. 实际项目应用(数据分析、图像处理等)
3. 性能优化技巧
4. 高级特性(内存映射、结构化数组等)

9.3 学习资源推荐

官方资源

  1. NumPy官方文档https://numpy.org/doc/
  2. NumPy用户指南https://numpy.org/doc/stable/user/index.html
  3. NumPy API参考https://numpy.org/doc/stable/reference/

中文资源

  1. NumPy中文文档https://www.numpy.org.cn/
  2. 菜鸟教程NumPy教程https://www.runoob.com/numpy/numpy-tutorial.html
  3. 莫烦Python NumPy教程https://mofanpy.com/tutorials/data-manipulation/numpy/

实战练习

  1. LeetCode上的NumPy题目
  2. Kaggle上的数据分析比赛
  3. 自己动手实现经典算法(如排序、搜索等)

9.4 常见面试问题

基础问题

  1. NumPy数组和Python列表有什么区别?
  2. 什么是广播机制?举例说明。
  3. 如何创建全0、全1、单位矩阵数组?

进阶问题

  1. 解释ndarray的strides属性。
  2. 如何优化NumPy代码性能?
  3. NumPy如何处理缺失值?

实战问题

  1. 用NumPy实现矩阵乘法。
  2. 计算数组的移动平均值。
  3. 如何用NumPy处理图像数据?

一句话总结

NumPy是Python科学计算的"心脏",它提供了高效的多维数组和丰富的数学函数,是数据科学、机器学习和科学计算领域不可或缺的基础工具。

相关推荐
好奇龙猫3 小时前
【人工智能学习-AI-MIT公开课11. 学习:识别树、无序】
人工智能·学习
玄同7653 小时前
我是如何学习编程的?——从 “扳手使用” 到编程学习:踩坑式实践的底层方法论
开发语言·人工智能·经验分享·笔记·python·学习·自然语言处理
xingzhemengyou13 小时前
Python lambda函数
开发语言·python
像风一样的男人@3 小时前
python --生成ico图标
java·python·spring
北岛寒沫3 小时前
北京大学 国家发展研究院 经济学原理课程笔记(第十七课 微观经济学的现代理论)
经验分享·笔记·学习
网安INF3 小时前
2025年我的年度总结
学习·博客之星
多打代码3 小时前
2026.1.2 删除二叉搜索树中的节点
开发语言·python·算法
laplace01233 小时前
Part 5|LangChain Agent 部署与上线流程(LangGraph 生态)
笔记·python·学习·语言模型·langchain
Dxy12393102163 小时前
Python MySQL 错误回滚实战代码
数据库·python·mysql