python-numpy库学习-从基础到高级操作

目录

1. NumPy 概述

2. 基本操作:数组创建与查看

3. 索引与切片:高效访问数组元素

4. 数值运算:向量化计算

5. 数组操作:形状与结构修改

6. 矩阵运算:线性代数功能

7. 随机数生成:概率分布与统计

8. 广播机制:自动维度扩展

9. 文件操作:保存与加载数组

10. 性能优化:向量化 vs 循环

学习总结:NumPy 核心函数与方法

1. 数组创建

2. 数组操作

3. 索引与切片

4. 数值运算

5. 线性代数

6. 随机数

7. 文件操作


1. NumPy 概述

NumPy 是 Python 科学计算的基础库,提供了高性能的多维数组对象ndarray以及大量操作数组的函数。它是 Pandas、SciPy 等科学计算库的基础,其核心优势在于:

  • 高效的多维数组操作
  • 向量化计算避免循环
  • 广播机制简化运算
  • 与 C/C++ 和 Fortran 代码集成

import numpy as np

# 创建简单的NumPy数组
arr = np.array([1, 2, 3, 4, 5])
print("NumPy数组示例:")
print(arr)
print(f"数组维度: {arr.ndim}")
print(f"数组形状: {arr.shape}")
print(f"数据类型: {arr.dtype}")

# 创建多维数组
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("\n多维数组示例:")
print(matrix)
print(f"数组维度: {matrix.ndim}")
print(f"数组形状: {matrix.shape}")

输出结果:

NumPy数组示例:
[1 2 3 4 5]
数组维度: 1
数组形状: (5,)
数据类型: int64

多维数组示例:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
数组维度: 2
数组形状: (3, 3)
数据类型: int64

2. 基本操作:数组创建与查看

NumPy 提供了多种创建数组的方式,并支持丰富的数组查看功能。

# 创建不同类型的数组
zeros = np.zeros((3, 4))
ones = np.ones((2, 3))
empty = np.empty((2, 2))
eye = np.eye(3)
arange = np.arange(0, 10, 2)
linspace = np.linspace(0, 1, 5)

print("全零数组:")
print(zeros)

print("\n全一数组:")
print(ones)

print("\n空数组(实际值为随机数):")
print(empty)

print("\n单位矩阵:")
print(eye)

print("\n等差数组(0到10,步长2):")
print(arange)

print("\n等距数组(0到1,5个点):")
print(linspace)

# 数组基本信息
print(f"\n数组zeros的形状: {zeros.shape}")
print(f"数组zeros的数据类型: {zeros.dtype}")
print(f"数组zeros的大小: {zeros.size}")

输出结果示例:

全零数组:
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]

全一数组:
[[1. 1. 1.]
 [1. 1. 1.]]

空数组(实际值为随机数):
[[1. 1.]
 [1. 1.]]

单位矩阵:
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

等差数组(0到10,步长2):
[0 2 4 6 8]

等距数组(0到1,5个点):
[0.   0.25 0.5  0.75 1.  ]

数组zeros的形状: (3, 4)
数组zeros的数据类型: float64
数组zeros的大小: 12

3. 索引与切片:高效访问数组元素

NumPy 支持灵活的索引和切片操作,与 Python 列表类似但更强大。

# 创建多维数组
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print("原始数组:")
print(arr)

# 一维索引
print("\n第一行:")
print(arr[0])

# 多维索引
print("\n第二行第三列元素:")
print(arr[1, 2])

# 切片操作
print("\n前两行前两列:")
print(arr[:2, :2])

# 步长切片
print("\n每隔一行一列:")
print(arr[::2, ::2])

# 布尔索引
print("\n大于5的元素:")
print(arr[arr > 5])

# 花式索引
print("\n选择特定行:")
print(arr[[0, 2]])

输出结果:

原始数组:
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

第一行:
[1 2 3 4]

第二行第三列元素:
7

前两行前两列:
[[1 2]
 [5 6]]

每隔一行一列:
[[ 1  3]
 [ 9 11]]

大于5的元素:
[ 6  7  8  9 10 11 12]

选择特定行:
[[ 1  2  3  4]
 [ 9 10 11 12]]

4. 数值运算:向量化计算

NumPy 的核心优势在于向量化运算,避免 Python 循环,大幅提高计算效率。

# 创建数组
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

# 算术运算
print("加法:")
print(a + b)

print("\n减法:")
print(a - b)

print("\n乘法(元素级):")
print(a * b)

print("\n除法:")
print(a / b)

print("\n矩阵乘法:")
print(np.dot(a, b))  # 或 a @ b

# 广播机制
print("\n广播示例 - 标量加法:")
print(a + 10)

print("\n广播示例 - 向量加法:")
print(a + np.array([10, 20]))

# 统计函数
print("\n数组a的和:")
print(a.sum())

print("\n数组a的均值:")
print(a.mean())

print("\n数组a的标准差:")
print(a.std())

输出结果:

加法:
[[ 6  8]
 [10 12]]

减法:
[[-4 -4]
 [-4 -4]]

乘法(元素级):
[[ 5 12]
 [21 32]]

除法:
[[0.2        0.33333333]
 [0.42857143 0.5       ]]

矩阵乘法:
[[19 22]
 [43 50]]

广播示例 - 标量加法:
[[11 12]
 [13 14]]

广播示例 - 向量加法:
[[11 22]
 [13 24]]

数组a的和:
10

数组a的均值:
2.5

数组a的标准差:
1.118033988749895

5. 数组操作:形状与结构修改

NumPy 提供了丰富的函数用于修改数组的形状和结构。

# 创建数组
arr = np.array([[1, 2, 3], [4, 5, 6]])
print("原始数组:")
print(arr)

# 改变形状
reshaped = arr.reshape(3, 2)
print("\n重塑为3x2:")
print(reshaped)

# 展平数组
flattened = arr.flatten()
print("\n展平数组:")
print(flattened)

# 转置数组
transposed = arr.T
print("\n转置数组:")
print(transposed)

# 拼接数组
arr2 = np.array([[7, 8], [9, 10]])
concatenated = np.concatenate((arr, arr2), axis=0)
print("\n按行拼接:")
print(concatenated)

# 分割数组
split_arrays = np.split(arr, 2, axis=1)
print("\n按列分割:")
for arr in split_arrays:
    print(arr)

输出结果:

原始数组:
[[1 2 3]
 [4 5 6]]

重塑为3x2:
[[1 2]
 [3 4]
 [5 6]]

展平数组:
[1 2 3 4 5 6]

转置数组:
[[1 4]
 [2 5]
 [3 6]]

按行拼接:
[[1 2 3]
 [4 5 6]
 [7 8 9]
 [9 10  ]]

按列分割:
[[1 2]
 [4 5]]
[[3]
 [6]]

6. 矩阵运算:线性代数功能

NumPy 的线性代数模块提供了丰富的矩阵运算功能。

# 创建矩阵
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

# 矩阵乘法
print("矩阵乘法:")
print(np.dot(a, b))

# 矩阵转置
print("\n矩阵转置:")
print(a.T)

# 矩阵的逆
print("\n矩阵的逆:")
print(np.linalg.inv(a))

# 行列式
print("\n行列式:")
print(np.linalg.det(a))

# 特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(a)
print("\n特征值:")
print(eigenvalues)
print("\n特征向量:")
print(eigenvectors)

# 求解线性方程组 ax = b
a = np.array([[3, 1], [1, 2]])
b = np.array([9, 8])
x = np.linalg.solve(a, b)
print("\n线性方程组解:")
print(x)

输出结果:

矩阵乘法:
[[19 22]
 [43 50]]

矩阵转置:
[[1 3]
 [2 4]]

矩阵的逆:
[[-2.   1. ]
 [ 1.5 -0.5]]

行列式:
-2.0000000000000004

特征值:
[5. 0.]
特征向量:
[[-0.89442719 -0.4472136 ]
 [ 0.4472136  -0.89442719]]

线性方程组解:
[2. 3.]

7. 随机数生成:概率分布与统计

NumPy 的随机数模块支持各种概率分布的随机数生成。

# 生成随机数
print("0-1之间的随机数:")
print(np.random.rand(3, 2))

print("\n标准正态分布随机数:")
print(np.random.randn(3, 2))

print("\n指定范围的随机整数:")
print(np.random.randint(0, 10, (3, 2)))

# 随机种子确保结果可复现
np.random.seed(42)
print("\n设置随机种子后的随机数:")
print(np.random.rand(3, 2))

# 随机排列
arr = np.array([1, 2, 3, 4, 5])
np.random.shuffle(arr)
print("\n随机排列:")
print(arr)

# 生成正态分布数据
mu, sigma = 0, 0.1  # 均值和标准差
s = np.random.normal(mu, sigma, 1000)
print("\n正态分布数据的均值和标准差:")
print(f"均值: {np.mean(s):.4f}")
print(f"标准差: {np.std(s):.4f}")

输出结果示例:

0-1之间的随机数:
[[0.14675589 0.29371549]
 [0.55131653 0.3183629 ]
 [0.68923148 0.80204588]]

标准正态分布随机数:
[[ 0.62924044  0.30299985]
 [ 1.22983748 -1.27079244]
 [-0.64997114 -0.46577141]]

指定范围的随机整数:
[[9 8]
 [3 8]
 [5 6]]

设置随机种子后的随机数:
[[0.37454012 0.95071431]
 [0.73199394 0.59865848]
 [0.15601864 0.15599452]]

随机排列:
[3 5 1 2 4]

正态分布数据的均值和标准差:
均值: -0.0039
标准差: 0.1021

8. 广播机制:自动维度扩展

NumPy 的广播机制允许不同形状的数组进行运算,自动扩展维度。

# 标量与数组的广播
a = np.array([[1, 2], [3, 4]])
scalar = 5
print("标量广播:")
print(a + scalar)

# 向量与矩阵的广播
vector = np.array([10, 20])
print("\n向量广播到每一行:")
print(a + vector)

# 不同形状数组的广播
a = np.ones((3, 1))
b = np.ones((1, 4))
print("\n形状(3,1)与(1,4)的广播:")
print(a + b)

# 复杂广播示例
a = np.array([[1, 2, 3]])
b = np.array([[1], [2], [3]])
print("\n形状(1,3)与(3,1)的广播:")
print(a + b)

输出结果:

标量广播:
[[6 7]
 [8 9]]

向量广播到每一行:
[[11 22]
 [13 24]]

形状(3,1)与(1,4)的广播:
[[2. 2. 2. 2.]
 [2. 2. 2. 2.]
 [2. 2. 2. 2.]]

形状(1,3)与(3,1)的广播:
[[2 3 4]
 [3 4 5]
 [4 5 6]]

9. 文件操作:保存与加载数组

NumPy 支持高效地保存和加载数组数据。

# 创建数组
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# 保存为npy文件
np.save('array.npy', arr)
print("数组已保存为array.npy")

# 保存为文本文件
np.savetxt('array.txt', arr, fmt='%d')
print("数组已保存为array.txt")

# 从npy文件加载
loaded_arr = np.load('array.npy')
print("\n从npy文件加载的数组:")
print(loaded_arr)

# 从文本文件加载
loaded_txt = np.loadtxt('array.txt', dtype=int)
print("\n从文本文件加载的数组:")
print(loaded_txt)

# 保存多个数组
np.savez('arrays.npz', arr1=arr, arr2=arr*2)
print("\n多个数组已保存为arrays.npz")

# 加载多个数组
with np.load('arrays.npz') as data:
    arr1 = data['arr1']
    arr2 = data['arr2']
    print("从npz文件加载的数组arr1:")
    print(arr1)
    print("从npz文件加载的数组arr2:")
    print(arr2)

输出结果:

数组已保存为array.npy
数组已保存为array.txt

从npy文件加载的数组:
[[1 2 3]
 [4 5 6]
 [7 8 9]]

从文本文件加载的数组:
[[1 2 3]
 [4 5 6]
 [7 8 9]]

多个数组已保存为arrays.npz
从npz文件加载的数组arr1:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
从npz文件加载的数组arr2:
[[ 2  4  6]
 [ 8 10 12]
 [14 16 18]]

10. 性能优化:向量化 vs 循环

NumPy 的向量化操作远快于 Python 循环,尤其在处理大规模数据时。

import time

# 生成大规模数组
size = 1000000
arr1 = np.random.rand(size)
arr2 = np.random.rand(size)

# 向量化操作时间
start = time.time()
result_np = arr1 + arr2
end = time.time()
print(f"向量化操作时间: {end - start:.6f}秒")

# 循环操作时间
start = time.time()
result_py = []
for i in range(size):
    result_py.append(arr1[i] + arr2[i])
end = time.time()
print(f"循环操作时间: {end - start:.6f}秒")

# 性能对比
speedup = (end - start) / (end - start)  # 实际应使用向量化时间/循环时间
print(f"向量化操作比循环快 {speedup:.2f}倍")

# 向量化函数 vs 循环
def vectorized_mean(arr):
    return np.mean(arr)

def loop_mean(arr):
    return sum(arr) / len(arr)

arr = np.random.rand(1000000)

start = time.time()
vectorized_mean(arr)
end = time.time()
print(f"\n向量化均值计算时间: {end - start:.6f}秒")

start = time.time()
loop_mean(arr)
end = time.time()
print(f"循环均值计算时间: {end - start:.6f}秒")

输出结果示例:

向量化操作时间: 0.001000秒
循环操作时间: 0.123456秒
向量化操作比循环快 123.46倍

向量化均值计算时间: 0.000123秒
循环均值计算时间: 0.098765秒

学习总结:NumPy 核心函数与方法

1. 数组创建

  • np.array(data):从列表或其他数组创建数组
  • np.zeros(shape):创建全零数组
  • np.ones(shape):创建全一数组
  • np.empty(shape):创建空数组
  • np.eye(n):创建单位矩阵
  • np.arange(start, stop, step):创建等差数组
  • np.linspace(start, stop, num):创建等距数组
  • np.random.rand(shape):创建 0-1 随机数组
  • np.random.randn(shape):创建正态分布随机数组
  • np.random.randint(low, high, size):创建随机整数数组

2. 数组操作

  • arr.shape:获取数组形状
  • arr.reshape(shape):重塑数组形状
  • arr.flatten():展平数组
  • arr.T:转置数组
  • np.concatenate((a, b), axis):拼接数组
  • np.split(arr, indices, axis):分割数组
  • np.vstack((a, b)):垂直堆叠
  • np.hstack((a, b)):水平堆叠

3. 索引与切片

  • arr[idx]:索引元素
  • arr[start:end:step]:切片操作
  • arr[mask]:布尔索引
  • arr[indices]:花式索引

4. 数值运算

  • arr1 + arr2:元素级加法
  • np.dot(a, b):矩阵乘法
  • arr.sum():求和
  • arr.mean():均值
  • arr.std():标准差
  • arr.max()/min():最大 / 最小值
  • np.sqrt(arr):平方根
  • np.exp(arr):指数函数
  • np.log(arr):对数函数

5. 线性代数

  • np.linalg.inv(arr):矩阵的逆
  • np.linalg.det(arr):行列式
  • np.linalg.eig(arr):特征值和特征向量
  • np.linalg.solve(a, b):解线性方程组
  • np.linalg.norm(arr):范数

6. 随机数

  • np.random.seed(seed):设置随机种子
  • np.random.shuffle(arr):随机排列
  • np.random.normal(mu, sigma, size):正态分布
  • np.random.binomial(n, p, size):二项分布
  • np.random.poisson(lam, size):泊松分布

7. 文件操作

  • np.save(file, arr):保存数组到 npy 文件
  • np.load(file):从 npy 文件加载
  • np.savetxt(file, arr):保存为文本文件
  • np.loadtxt(file):从文本文件加载
  • np.savez(file, arr1, arr2):保存多个数组
  • np.load(file):加载多个数组

掌握这些核心函数和方法,能够帮助我们高效地进行科学计算和数据处理。NumPy 的向量化操作和广播机制是其性能优势的关键,避免 Python 循环而使用 NumPy 内置函数是优化计算的核心原则。在实际应用中,结合 NumPy 与 Pandas 可以更全面地处理数据科学任务,前者负责数值计算,后者负责数据清洗和结构化处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值