Python 科学计算与数据分析三剑客:NumPy、Pandas、SciPy 完全指南
Python 科学计算与数据分析三剑客:NumPy、Pandas、SciPy 完全指南
专栏:Python 常用工具库实战教程 | 第一篇
适合人群:Python 初学者、数据分析师、科研人员、算法工程师
目录
前言
在 Python 的数据科学生态系统中,有三个库几乎是所有数据相关工作的起点:NumPy、Pandas 和 SciPy。它们分别对应三个层次的需求:
| 库 | 定位 | 一句话描述 | 学习难度 |
|---|---|---|---|
| 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
- 大小为 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》—— 从静态图表到交互式可视化,让数据说话!
更多推荐



所有评论(0)