【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科学计算的"心脏",它提供了高效的多维数组和丰富的数学函数,是数据科学、机器学习和科学计算领域不可或缺的基础工具。

相关推荐
Yan-英杰2 分钟前
【论文精读】 基于 TensorFlow 对卷积神经网络的优化研究:异构式 CPU+GPU 协同计算 + ReLU-Swish 激活函数
python·卷积神经网络
ydjs678899-bot21 分钟前
如何在Java中打印pdf静默打印和打印对话框选择
java·python·pdf
m4Rk_42 分钟前
【论文阅读】Agent 记忆机制(102):UMA——用多个未来问题端到端训练一份共享记忆
论文阅读·人工智能·学习·开源·github
xxwl5851 小时前
第六章---计算几何
笔记·学习·算法
minglie11 小时前
Visual Studio问题
学习
其实防守也摸鱼1 小时前
存储管理:页面置换算法学习任务(测验题要求给出置换页面顺序,缺页次数,缺页率)
android·前端·数据库·学习·oracle·自动化
dadaobusi1 小时前
学习: gdb自动捕获调用栈
学习
Song_RsHt1 小时前
Gateway (上):路由与转发,微服务的统一入口
java·笔记·后端·学习·gateway
把我格子衫拿来1 小时前
误差预算怎么做?从雅可比到蒙特卡洛的三维定位不确定度分析
python·蒙特卡洛·三维定位·误差分析·不确定度
2603_969579281 小时前
备份云盘是什么意思?简单说就是“用云盘来备份数据”
学习