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 元素总数 9 shape 各元素的乘积
dtype 数据类型 int64 所有元素的类型
nbytes 内存占用 72 size × 每个元素字节数

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()}")

稀疏矩阵格式对比:

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

总结

三剑客选择指南

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

学习路线建议

在这里插入图片描述

完整依赖安装

pip install numpy pandas scipy openpyxl

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

更多推荐