Python 科学计算与数据分析三剑客:NumPy、Pandas、SciPy 完全指南

专栏:Python 常用工具库实战教程 | 第一篇
适合人群:Python 初学者、数据分析师、科研人员、算法工程师


目录


前言

在 Python 的数据科学生态系统中,有三个库几乎是所有数据相关工作的起点:NumPyPandasSciPy。它们分别对应三个层次的需求:

定位一句话描述学习难度
NumPy底层计算引擎多维数组与矩阵运算的基石⭐⭐
Pandas数据处理工具像操作 Excel 一样操作数据⭐⭐
SciPy高级计算工具箱优化、信号处理、统计分析⭐⭐⭐

这三个库构成了一个金字塔结构

在这里插入图片描述

Pandas 构建在 NumPy 之上,SciPy 则同时依赖两者。理解这个依赖关系,有助于你更好地掌握它们的使用场景。

本文将带你从零开始,系统学习这三个库的核心功能,并通过大量实战代码帮助你快速上手。


第一章:NumPy —— Python 科学计算的基石

1.1 NumPy 是什么

NumPy(Numerical Python)是 Python 中最基础的科学计算库。它提供了一个高性能的多维数组对象 ndarray,以及一套用于操作这些数组的工具。

NumPy 的核心优势:

  • 性能:底层用 C 语言实现,比纯 Python 快 10-100 倍
  • 便捷:支持向量化操作,无需编写循环
  • 生态:Pandas、Matplotlib、Scikit-learn 等都基于 NumPy

1.2 安装与导入

pip install numpy
import numpy as np  # 约定俗成的导入方式

1.3 数组的创建

NumPy 提供了多种创建数组的方式:

从 Python 列表创建
import numpy as np

# 一维数组
arr = np.array([1, 2, 3, 4, 5])
# 输出: [1 2 3 4 5]

# 二维数组(矩阵)
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 输出:
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

# 指定数据类型
arr_float = np.array([1, 2, 3], dtype=np.float32)

输出结果:

一维数组: [1 2 3 4 5]
二维数组:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
指定类型: [1. 2. 3.]
特殊数组创建函数
函数说明示例
np.zeros(shape)创建全零数组np.zeros((3, 3)) → 3×3 全零矩阵
np.ones(shape)创建全一数组np.ones((2, 4)) → 2×4 全一矩阵
np.arange(start, stop, step)等差序列(类似 range)np.arange(0, 10, 2)[0,2,4,6,8]
np.linspace(start, stop, num)等间距 num 个点np.linspace(0, 1, 5)[0,0.25,0.5,0.75,1]
np.eye(n)单位矩阵np.eye(3) → 3×3 单位矩阵
np.random.rand(d0,d1,...)均匀分布随机数np.random.rand(3,3) → 3×3 随机矩阵
np.random.randn(d0,d1,...)标准正态分布np.random.randn(100) → 100个正态分布数

实际运行效果:

arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.zeros((3, 3))
arr3 = np.ones((2, 4))
arr4 = np.arange(0, 10, 2)        # [0, 2, 4, 6, 8]
arr5 = np.linspace(0, 1, 5)       # 等间距5个点

# 一维数组: [1 2 3 4 5]
# 全零矩阵:
# [[0. 0. 0.]
#  [0. 0. 0.]
#  [0. 0. 0.]]
# 全一矩阵:
# [[1. 1. 1. 1.]
#  [1. 1. 1. 1.]]
# arange: [0 2 4 6 8]
# linspace: [0.   0.25 0.5 0.75 1. ]

1.4 数组的核心属性

每个 NumPy 数组都有以下关键属性:

matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(f"形状 (shape): {matrix.shape}")      # (3, 3)
print(f"维度 (ndim): {matrix.ndim}")        # 2
print(f"元素总数 (size): {matrix.size}")    # 9
print(f"数据类型 (dtype): {matrix.dtype}")  # int64
print(f"内存大小 (nbytes): {matrix.nbytes} bytes")  # 72 bytes

属性说明表:

属性含义示例值说明
shape数组形状(3, 3)每个维度的元素个数
ndim维度数2几维数组
size元素总数9shape 各元素的乘积
dtype数据类型int64所有元素的类型
nbytes内存占用72size × 每个元素字节数

1.5 向量化运算

NumPy 最强大的特性之一就是向量化运算——对整个数组执行操作,而无需编写循环。

a = np.array([1, 2, 3, 4])
b = np.array([10, 20, 30, 40])

# 算术运算
print(a + b)        # [11 22 33 44]
print(a * b)        # [ 10  40  90 160]
print(a ** 2)       # [ 1  4  9 16]

# 比较运算(返回布尔数组)
print(a > 2)        # [False False  True  True]

# 统计运算
print(np.sum(a))    # 10
print(np.mean(a))   # 2.5
print(np.std(a))    # 1.118
print(np.max(a))    # 4
print(np.min(a))    # 1

向量化运算 vs Python 循环的性能差异:

# 实际运行结果(100万元素):
# Python 原生耗时: 75.54 ms
# NumPy 耗时: 6.83 ms
# NumPy 加速比: 11.1x

性能提示:NumPy 越大越快。当数据量达到百万级时,NumPy 的优势尤为明显。这是因为 NumPy 在连续内存块上执行向量化操作,充分利用了 CPU 的 SIMD 指令集。

1.6 索引与切片

NumPy 数组支持与 Python 列表类似的索引和切片操作:

一维数组索引
arr = np.array([10, 20, 30, 40, 50, 60, 70, 80])

print(arr[2])       # 30          —— 单个元素
print(arr[1:5])     # [20 30 40 50] —— 切片
print(arr[::2])     # [10 30 50 70] —— 步长为2
print(arr[-1])      # 80          —— 负索引(从末尾开始)
print(arr[::-1])    # [80 70 60 50 40 30 20 10] —— 反转
二维数组索引
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

print(matrix[0, 1])   # 2     —— 第0行第1列
print(matrix[1, :])   # [4 5 6] —— 第1行(所有列)
print(matrix[:, 2])   # [3 6 9] —— 第2列(所有行)
print(matrix[0:2, 1:3])
# [[2 3]
#  [5 6]]   —— 子矩阵

重要区别:NumPy 切片返回的是**视图(view)**而非副本。修改切片会影响原始数组!如果需要独立副本,使用 arr.copy()

1.7 广播机制

广播(Broadcasting) 是 NumPy 最优雅的特性之一。它允许不同形状的数组进行算术运算,NumPy 会自动扩展较小的数组。

matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
row_vector = np.array([10, 20, 30])

# row_vector 会被自动"广播"到每一行
result = matrix + row_vector

# [[11 22 33]
#  [14 25 36]
#  [17 28 39]]

广播规则:

  1. 如果两个数组的维度不同,较小维度的数组会在前面补 1
  2. 每个维度的大小要么相等,要么其中一个为 1
  3. 大小为 1 的维度会被"拉伸"以匹配另一个数组

在这里插入图片描述

1.8 线性代数运算

NumPy 提供了完整的线性代数模块 np.linalg

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 矩阵乘法
print(A @ B)
# [[19 22]
#  [43 50]]

# 转置
print(A.T)
# [[1 3]
#  [2 4]]

# 行列式
print(np.linalg.det(A))  # -2.00

# 逆矩阵
print(np.linalg.inv(A))
# [[-2.   1. ]
#  [ 1.5 -0.5]]

# 特征值
eigenvalues, eigenvectors = np.linalg.eig(A)
print(eigenvalues)  # [-0.372, 5.372]

常用线性代数函数速查:

函数说明示例
np.linalg.det(A)行列式det(A) = ad - bc
np.linalg.inv(A)逆矩阵A × A⁻¹ = I
np.linalg.eig(A)特征值和特征向量Av = λv
np.linalg.svd(A)奇异值分解A = UΣVᵀ
np.linalg.solve(A, b)解线性方程组Ax = b
np.linalg.norm(A)范数2-范数、F-范数等

1.9 随机数生成

NumPy 提供了强大的随机数生成模块:

np.random.seed(42)  # 设置随机种子,保证结果可复现

# 随机整数
print(np.random.randint(0, 10, size=5))     # [6 3 7 4 6]

# 随机浮点数 [0, 1)
print(np.random.random(5))                  # [0.446 0.100 0.459 ...]

# 正态分布
print(np.random.randn(5))                   # [-0.483 0.164 ...]

# 均匀分布 [a, b)
print(np.random.uniform(1, 100, size=5))    # [1.70 3.28 52.95 ...]

# 随机排列
arr = np.array([1, 2, 3, 4, 5])
print(np.random.permutation(arr))           # [3 1 5 2 4]

# 随机抽样
print(np.random.choice([10, 20, 30, 40], size=3))  # [20 40 10]

1.10 性能对比

让我们用实际数据验证 NumPy 的性能优势:

import time

size = 1_000_000

# Python 原生
start = time.time()
py_list = list(range(size))
py_result = [x * 2 + 1 for x in py_list]
py_time = time.time() - start

# NumPy
start = time.time()
np_arr = np.arange(size)
np_result = np_arr * 2 + 1
np_time = time.time() - start

print(f"Python 原生耗时: {py_time*1000:.2f} ms")   # ~75 ms
print(f"NumPy 耗时: {np_time*1000:.2f} ms")         # ~7 ms
print(f"NumPy 加速比: {py_time/np_time:.1f}x")      # ~11x

为什么 NumPy 这么快?

在这里插入图片描述

维度Python 原生NumPy
内存布局分散(指针+对象)连续(原始数据)
类型检查每次运算检查一次性确定
循环Python 解释器循环C 层面循环
SIMD 优化不支持支持

第二章:Pandas —— 数据分析的瑞士军刀

2.1 Pandas 是什么

Pandas(Python Data Analysis Library)是基于 NumPy 构建的数据分析库。它提供了两个核心数据结构:Series(一维)和 DataFrame(二维),让你可以像操作 Excel 表格一样处理数据。

Pandas 的核心能力:

  • 数据读写:CSV、Excel、SQL、JSON、Parquet 等格式
  • 数据清洗:缺失值处理、重复值删除、数据类型转换
  • 数据筛选:条件查询、多条件组合
  • 数据聚合:groupby、透视表、交叉表
  • 时间序列:日期处理、重采样、滑动窗口
pip install pandas
import pandas as pd

2.2 Series:带标签的一维数组

Series 是 Pandas 最基本的数据结构,可以看作 DataFrame 的一列。

s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
print(s)
# a    10
# b    20
# c    30
# d    40

print(s['b'])       # 20  —— 按标签索引
print(s[1])          # 20  —— 按位置索引
print(s[s > 20])     # c 30 / d 40  —— 条件筛选

2.3 DataFrame:二维表格数据结构

DataFrame 是 Pandas 的核心,可以理解为一个电子表格:

data = {
    '姓名': ['张三', '李四', '王五', '赵六'],
    '年龄': [25, 30, 35, 28],
    '部门': ['技术部', '市场部', '技术部', '人事部'],
    '薪资': [15000, 18000, 25000, 12000],
}
df = pd.DataFrame(data)

实际运行输出:

   姓名  年龄   部门     薪资
0  张三  25  技术部  15000
1  李四  30  市场部  18000
2  王五  35  技术部  25000
3  赵六  28  人事部  12000

基本属性:

df.shape      # (4, 4) —— 行数、列数
df.dtypes     # 每列的数据类型
df.head(3)    # 前3行
df.tail(2)    # 后2行
df.info()     # 完整信息概览
df.describe() # 数值列的统计摘要

describe() 输出示例:

              年龄          薪资
count   4.000000      4.000000
mean   29.500000  17500.000000
std     4.203173   5259.907574
min    25.000000  12000.000000
25%    27.250000  14250.000000
50%    29.000000  16500.000000
75%    31.250000  19750.000000
max    35.000000  25000.000000

2.4 数据读取与写入

Pandas 支持几乎所有常见的数据格式:

CSV 文件
# 读取
df = pd.read_csv('data.csv', encoding='utf-8')
df = pd.read_csv('data.csv', encoding='gbk')      # 中文编码

# 写出
df.to_csv('output.csv', index=False, encoding='utf-8-sig')

执行后会生成 output.csv 文件,内容为:

姓名,年龄,部门,薪资,入职日期,评分
张三,25,技术部,15000,2020-03-15,88.5
李四,30,市场部,18000,2019-07-22,92.3
...
Excel 文件
# 需要安装 openpyxl: pip install openpyxl
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
df.to_excel('output.xlsx', index=False)

# 读取多个sheet
xlsx = pd.ExcelFile('data.xlsx')
df1 = pd.read_excel(xlsx, 'Sheet1')
df2 = pd.read_excel(xlsx, 'Sheet2')
JSON 文件
df = pd.read_json('data.json')
df.to_json('output.json', orient='records', force_ascii=False)

文件格式选择指南:

格式优点缺点适用场景
CSV通用、轻量无类型信息小数据、数据交换
Excel兼容性好、多sheet文件大、速度慢报表、业务数据
Parquet列式存储、压缩好需要额外库大数据、数据仓库
JSON层次结构、Web 友好文件大API 数据、配置
HDF5高性能、支持压缩复杂科学计算

2.5 数据选择与索引

列选择
# 选择单列(返回 Series)
names = df['姓名']

# 选择多列(返回 DataFrame)
subset = df[['姓名', '薪资']]
行选择
# loc —— 按标签选择
df.loc[0]                    # 第0行
df.loc[0:2, ['姓名', '薪资']]  # 第0-2行的指定列

# iloc —— 按位置选择
df.iloc[0]                   # 第1行
df.iloc[0:3, 0:2]            # 前3行、前2列
条件筛选
# 单条件
high_salary = df[df['薪资'] > 20000]

# 多条件(& = and, | = or)
tech_high = df[(df['部门'] == '技术部') & (df['评分'] > 90)]

# isin 过滤
selected = df[df['部门'].isin(['技术部', '市场部'])]

# query 方法(更简洁)
result = df.query('薪资 > 20000 and 年龄 < 35')

2.6 数据清洗

真实数据往往充满"脏"数据。Pandas 提供了丰富的工具来清洗数据:

缺失值处理
# 检测缺失值
df.isnull()           # 返回布尔矩阵
df.isnull().sum()     # 每列缺失值数量

# 删除缺失值
df.dropna()                    # 删除包含缺失值的行
df.dropna(subset=['姓名'])     # 仅检查指定列
df.dropna(how='all')           # 所有列都缺失才删除

# 填充缺失值
df.fillna(0)                           # 用0填充
df.fillna({'姓名': '未知', '薪资': 0})  # 分列填充
df.fillna(df.mean())                   # 用均值填充数值列
df.fillna(method='ffill')              # 用前一个值填充
df.fillna(method='bfill')              # 用后一个值填充
重复值处理
df.duplicated()              # 检测重复行
df.drop_duplicates()         # 删除完全重复的行
df.drop_duplicates(subset=['姓名'])  # 按指定列去重
数据类型转换
df['薪资'] = df['薪资'].astype(float)     # 转为浮点
df['年龄'] = pd.to_numeric(df['年龄'])     # 安全转换
df['入职日期'] = pd.to_datetime(df['入职日期'])  # 转为日期

实际运行清洗效果:

# 缺失值统计:
# 姓名    1
# 年龄    1
# 薪资    1
# 邮箱    0

# 去重前行数: 7
# 去重后行数: 5

# 填充缺失值后:
#     姓名    年龄       薪资
# 0   张三  25.0   15000.0
# 1   李四  30.0   18000.0
# 2   未知  35.0   25000.0
# 3   赵六  31.2   12000.0
# 4   孙七  42.0   16500.0

2.7 分组与聚合

groupby 是 Pandas 最强大的功能之一,类似于 SQL 的 GROUP BY:

# 单列分组
dept_stats = df.groupby('部门').agg(
    人数=('姓名', 'count'),
    平均薪资=('薪资', 'mean'),
    最高薪资=('薪资', 'max'),
    平均评分=('评分', 'mean')
).round(1)

实际输出:

       人数   平均薪资  最高薪资  平均评分
部门
人事部    2  12500.0  13000  79.6
市场部    3  25333.3  30000  92.3
技术部    3  20666.7  25000  91.1

常用聚合函数:

函数说明
count非缺失值个数
sum求和
mean均值
median中位数
std标准差
min / max最小/最大值
first / last第一个/最后一个值
nunique不同值的个数

多列分组:

# 按部门和薪资等级分组
df['薪资等级'] = pd.cut(df['薪资'], bins=[0, 15000, 25000, 100000],
                         labels=['初级', '中级', '高级'])
result = df.groupby(['部门', '薪资等级']).size()

2.8 数据透视表

透视表是将数据"重塑"的利器:

pivot = df.pivot_table(
    values='薪资',
    index='部门',
    aggfunc=['count', 'mean', 'max', 'min']
).round(0)

实际输出:

      count     mean      max      min
部门
人事部     2  12500.0  13000.0  12000.0
市场部     3  25333.0  30000.0  18000.0
技术部     3  20667.0  25000.0  15000.0

pivot_table 参数说明:

参数说明示例
values要聚合的列'薪资'
index行标签'部门'
columns列标签'薪资等级'
aggfunc聚合函数'mean'['mean', 'max']
fill_value缺失值填充0
margins是否添加总计行True

2.9 合并与连接

Pandas 提供了类似 SQL JOIN 的合并功能:

# 内连接(只保留匹配的行)
pd.merge(df1, df2, on='员工ID', how='inner')

# 左连接(保留左表所有行)
pd.merge(df1, df2, on='员工ID', how='left')

# 右连接(保留右表所有行)
pd.merge(df1, df2, on='员工ID', how='right')

# 外连接(保留所有行)
pd.merge(df1, df2, on='员工ID', how='outer')

# 按不同列名合并
pd.merge(df1, df2, left_on='emp_id', right_on='employee_id')

# 纵向拼接
pd.concat([df1, df2], axis=0)  # 上下拼接
pd.concat([df1, df2], axis=1)  # 左右拼接

合并方式示意图:

在这里插入图片描述

2.10 实战案例:员工数据分析

让我们用一个完整的案例来展示 Pandas 的实战能力:

import pandas as pd
import numpy as np

# 创建员工数据
data = {
    '姓名': ['张三', '李四', '王五', '赵六', '孙七', '周八', '吴九', '郑十'],
    '年龄': [25, 30, 35, 28, 42, 33, 27, 38],
    '部门': ['技术部', '市场部', '技术部', '人事部', '市场部', '技术部', '人事部', '市场部'],
    '薪资': [15000, 18000, 25000, 12000, 30000, 22000, 13000, 28000],
    '评分': [88.5, 92.3, 95.1, 76.8, 91.0, 89.7, 82.4, 93.6]
}
df = pd.DataFrame(data)

# 1. 按部门统计薪资
dept_stats = df.groupby('部门')['薪资'].agg(['mean', 'max', 'min'])

# 2. 找出薪资最高的前3名
top3 = df.nlargest(3, '薪资')[['姓名', '部门', '薪资']]

# 3. 添加工龄和评级列
df['工龄'] = 2025 - pd.to_datetime(['2020-03-15', '2019-07-01', '2017-11-20',
                                      '2021-06-10', '2015-02-28', '2018-09-01',
                                      '2022-01-15', '2016-05-18']).year

df['状态'] = np.where(df['评分'] >= 90, '优秀',
                      np.where(df['评分'] >= 80, '良好', '一般'))

实际输出:

# 薪资最高的前3名:
#    姓名   部门     薪资
# 4  孙七  市场部  30000
# 7  郑十  市场部  28000
# 2  王五  技术部  25000

# 评分状态:
#    姓名    评分  状态
# 0  张三  88.5  良好
# 1  李四  92.3  优秀
# 2  王五  95.1  优秀
# 3  赵六  76.8  一般
# 4  孙七  91.0  优秀
# 5  周八  89.7  良好
# 6  吴九  82.4  良好
# 7  郑十  93.6  优秀

第三章:SciPy —— 高级科学计算

3.1 SciPy 简介

SciPy 是建立在 NumPy 之上的高级科学计算库,提供了大量的数学算法和工具。它不是替代 NumPy,而是在 NumPy 基础上提供了更高级的功能。

pip install scipy
import scipy
from scipy import optimize, signal, stats, sparse

SciPy 的主要子模块:

子模块用途常用函数
scipy.optimize优化与求根minimize, curve_fit, root
scipy.signal信号处理fft, filtfilt, find_peaks
scipy.stats统计分析ttest_ind, pearsonr, describe
scipy.sparse稀疏矩阵csr_matrix, csc_matrix, sparse.linalg
scipy.integrate数值积分quad, odeint
scipy.interpolate插值interp1d, CubicSpline
scipy.linalg高级线性代数lu, qr, svd

3.2 优化算法

scipy.optimize 提供了各种优化算法,常用于求函数最小值、拟合曲线等:

from scipy import optimize
import numpy as np

# 定义目标函数
def objective(x):
    return x**2 + 10*np.sin(x)

# 求最小值
result = optimize.minimize(objective, x0=0)
print(f"最小值点: x = {result.x[0]:.4f}")
print(f"最小值: f(x) = {result.fun:.4f}")

# 曲线拟合(例如:拟合指数衰减曲线)
def decay(t, A, lambda_, C):
    return A * np.exp(-lambda_ * t) + C

t_data = np.array([0, 1, 2, 3, 4, 5])
y_data = np.array([10, 6.1, 3.7, 2.2, 1.4, 0.9])

params, covariance = optimize.curve_fit(decay, t_data, y_data)
print(f"拟合参数: A={params[0]:.2f}, λ={params[1]:.2f}, C={params[2]:.2f}")

3.3 信号处理

scipy.signal 提供了数字信号处理工具:

from scipy import signal
import numpy as np

# 生成含噪声的信号
t = np.linspace(0, 1, 1000)
clean_signal = np.sin(2 * np.pi * 5 * t)  # 5Hz 正弦波
noisy_signal = clean_signal + 0.5 * np.random.randn(len(t))

# 设计低通滤波器
b, a = signal.butter(4, 0.05)  # 4阶巴特沃斯,截止频率0.05
filtered = signal.filtfilt(b, a, noisy_signal)

# 快速傅里叶变换
freqs = np.fft.fftfreq(len(t), t[1] - t[0])
fft_result = np.fft.fft(clean_signal)

3.4 统计分析

scipy.stats 提供了丰富的统计工具:

from scipy import stats

# 生成两组样本
group_a = np.random.normal(70, 10, 100)
group_b = np.random.normal(75, 10, 100)

# t 检验(比较两组均值是否有显著差异)
t_stat, p_value = stats.ttest_ind(group_a, group_b)
print(f"t 统计量: {t_stat:.4f}")
print(f"p 值: {p_value:.4f}")
print(f"差异显著: {'是' if p_value < 0.05 else '否'}")

# 相关系数
corr, p_val = stats.pearsonr(group_a, group_b)
print(f"Pearson 相关系数: {corr:.4f}")

# 正态性检验
stat, p = stats.shapiro(group_a)
print(f"Shapiro-Wilk 检验 p值: {p:.4f}")
print(f"数据近似正态: {'是' if p > 0.05 else '否'}")

# 描述性统计
desc = stats.describe(group_a)
print(f"均值: {desc.mean:.2f}")
print(f"方差: {desc.variance:.2f}")
print(f"偏度: {desc.skewness:.4f}")
print(f"峰度: {desc.kurtosis:.4f}")

3.5 稀疏矩阵

在处理大规模稀疏数据(如推荐系统、文本向量化)时,scipy.sparse 能极大节省内存:

from scipy import sparse
import numpy as np

# 创建稀疏矩阵
# 方式1:从密集矩阵转换
dense = np.array([[1, 0, 0, 2], [0, 0, 3, 0], [4, 0, 0, 5]])
sparse_matrix = sparse.csr_matrix(dense)
print(f"密集矩阵大小: {dense.nbytes} bytes")
print(f"稀疏矩阵大小: {sparse_matrix.data.nbytes + sparse_matrix.indices.nbytes + sparse_matrix.indptr.nbytes} bytes")

# 方式2:直接构建(COO格式)
rows = [0, 0, 1, 2, 2]
cols = [0, 3, 2, 0, 3]
data = [1, 2, 3, 4, 5]
sparse_coo = sparse.coo_matrix((data, (rows, cols)), shape=(3, 4))

# 稀疏矩阵运算
result = sparse_matrix @ np.array([1, 2, 3, 4])
print(f"矩阵向量乘法结果: {result.toarray()}")

稀疏矩阵格式对比:

格式全名优点缺点适用场景
COOCoordinate构建简单不支持运算初始构建
CSRCompressed Sparse Row行切片快列切片慢矩阵向量乘法
CSCCompressed Sparse Column列切片快行切片慢方程组求解
LILList of Lists增删元素快运算慢动态构建
DOKDictionary of Keys随机访问快运算慢逐元素构建

总结

三剑客选择指南

你的需求推荐工具原因
纯数学运算、矩阵计算NumPy底层高效,API 简洁
处理表格数据、Excel/CSVPandas读写方便,分析功能丰富
读取 SQL 数据做分析Pandaspd.read_sql() 一行搞定
数据清洗、缺失值处理Pandas专门的清洗方法集
统计检验、假设检验SciPy.stats完整的统计检验工具
信号处理、滤波SciPy.signal数字信号处理全套
曲线拟合、最优化SciPy.optimize多种优化算法
大规模稀疏矩阵SciPy.sparse内存高效

学习路线建议

在这里插入图片描述

完整依赖安装

pip install numpy pandas scipy openpyxl

下一篇预告:《Python 数据可视化完全指南:Matplotlib + Seaborn + Plotly》—— 从静态图表到交互式可视化,让数据说话!

更多推荐