目录
-
- [第3节:从表格到矩阵------NumPy 高级索引与维度变换实战](#第3节:从表格到矩阵——NumPy 高级索引与维度变换实战)
- 本节学习目标
- 为什么学这个
- 核心知识点讲解
-
- [一、花式索引(Fancy Indexing)------精准定位任意元素](#一、花式索引(Fancy Indexing)——精准定位任意元素)
- 二、布尔索引------用条件筛选数据
- 三、维度变换------数据的"变形术"
-
- reshape------改变数组的形状
- [ravel 和 flatten------把多维数组拉平](#ravel 和 flatten——把多维数组拉平)
- transpose------转置(行列互换)
- [swapaxes 和 moveaxis------交换/移动轴](#swapaxes 和 moveaxis——交换/移动轴)
- 四、数组的拼接与拆分
- 五、矩阵运算------线性代数基础
- 代码示例:综合实战
- 实战练习
- 本节总结
- 下一节预告
专栏导读
🌸 欢迎来到Python办公自动化专栏---Python处理办公问题,解放您的双手
🏳️🌈 个人博客主页:请点击------> 个人的博客主页 求收藏
🏳️🌈 Github主页:请点击------> Github主页 求Star⭐
🏳️🌈 知乎主页:请点击------> 知乎主页 求关注
🏳️🌈 CSDN博客主页:请点击------> CSDN的博客主页 求关注
👍 该系列文章专栏:请点击------>Python办公自动化专栏 求订阅
🕷 此外还有爬虫专栏:请点击------>Python爬虫基础专栏 求订阅
📕 此外还有python基础专栏:请点击------>Python基础学习专栏 求订阅
文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
❤️ 欢迎各位佬关注! ❤️
第3节:从表格到矩阵------NumPy 高级索引与维度变换实战
本节学习目标
完成本节学习后,你将能够:
- 掌握花式索引(Fancy Indexing),用索引数组提取任意位置的元素
- 熟练使用布尔索引进行条件筛选
- 理解并运用 reshape、transpose、swapaxes 等维度变换操作
- 掌握数组的拼接(concatenate/stack)和拆分(split)
- 了解基本的矩阵运算(点积、逆矩阵、行列式等)
- 综合运用高级技巧解决实际数据处理问题
为什么学这个
想象一下,你面前有一张包含 10000 条客户信息的 Excel 表格,老板问你:"帮我找出所有年龄大于 30 岁、消费金额超过 5000 元的女性客户"。
如果你还在用 for 循环逐行检查,就像在一堆文件里一页一页翻找------既慢又累。而 NumPy 的高级索引,就像给表格装上了"智能搜索引擎",你只需说出条件,它瞬间就能找到答案。
维度变换也是一项关键技能。数据在不同分析阶段可能需要不同的"形态"------有时你需要把一行数据变成一列,有时需要交换行和列,有时需要把多个表格拼在一起。掌握维度变换,就像掌握了变形金刚的"变身术"。
比喻:如果说第2节学的是"如何操作一个收纳盒",那么第3节学的就是"如何在多个收纳盒之间灵活搬移、重组、筛选物品"。这是从"会用工具"到"精通工具"的跨越。
核心知识点讲解
一、花式索引(Fancy Indexing)------精准定位任意元素
什么是花式索引?
花式索引指的是使用整数数组作为索引,一次性提取多个不连续位置的元素。它之所以叫"花式",是因为它比普通的切片灵活得多。
python
import numpy as np
# 创建一个示例数组
arr = np.array([10, 20, 30, 40, 50, 60, 70, 80])
# 普通切片:只能取连续的元素
print("切片 [1:4]:", arr[1:4]) # [20 30 40]
# 花式索引:可以取任意位置的元素
indices = [1, 3, 5, 7]
print("花式索引 [1,3,5,7]:", arr[indices]) # [20 40 60 80]
# 索引可以重复
indices2 = [0, 0, 7, 7, 3]
print("重复索引 [0,0,7,7,3]:", arr[indices2]) # [10 10 80 80 40]
# 用负数索引
print("负数索引 [-1,-3,-5]:", arr[[-1, -3, -5]]) # [80 60 40]
重要区别 :花式索引返回的是副本(copy),而不是视图(view)。这意味着对结果的修改不会影响原数组。这与切片不同(切片返回视图)。
python
# 切片返回视图(修改会影响原数组)
arr = np.array([1, 2, 3, 4, 5])
sub_slice = arr[1:3]
sub_slice[0] = 99
print("修改切片后原数组:", arr) # [ 1 99 3 4 5]
# 花式索引返回副本(修改不影响原数组)
sub_fancy = arr[[1, 2]]
sub_fancy[0] = 88
print("修改花式索引后原数组:", arr) # [ 1 99 3 4 5],不变
二维数组的花式索引
python
matrix = np.array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
# 提取指定的行
print("提取第0行和第2行:")
print(matrix[[0, 2]])
# 提取指定的列
print("\n提取第1列和第3列:")
print(matrix[:, [1, 3]])
# 提取指定的行列交叉点(一维结果)
print("\n提取 (0,1), (1,2), (2,3):")
print(matrix[[0, 1, 2], [1, 2, 3]]) # [2, 7, 12]
# 先选行再选列(二维结果)
print("\n先选行[0,2],再选列[1,3]:")
print(matrix[[0, 2]][:, [1, 3]])
# [[ 2 4]
# [10 12]]
# np.ix_ 构造交叉索引(优雅写法)
print("\n使用 np.ix_ 提取交叉区域:")
rows = [0, 2]
cols = [1, 3]
print(matrix[np.ix_(rows, cols)])
# [[ 2 4]
# [10 12]]
实际场景:花式索引在数据筛选中非常有用。比如你有一个用户行为日志数组,你想提取第 3、7、15、42 天的数据进行重点分析,花式索引一行代码就搞定。
二、布尔索引------用条件筛选数据
基本概念
布尔索引使用布尔数组(True/False)作为索引。只有对应位置为 True 的元素才会被选中。
python
arr = np.array([15, 28, 35, 42, 18, 56, 33, 71])
# 创建布尔条件
mask = arr > 30
print("条件 arr > 30:", mask)
# [False False True True False True True True]
# 用布尔数组筛选
print("大于30的元素:", arr[mask])
# [35 42 56 33 71]
# 一行写法(推荐)
print("大于30的元素:", arr[arr > 30])
组合条件
python
scores = np.array([85, 92, 58, 76, 45, 88, 63, 95])
# 逻辑与 (&):同时满足多个条件
print("60~90分之间:", scores[(scores >= 60) & (scores <= 90)])
# [85 76 88 63]
# 逻辑或 (|):满足任一条件
print("低于60或高于90:", scores[(scores < 60) | (scores > 90)])
# [58 45 92 95]
# 逻辑非 (~):取反
print("不在70~80之间:", scores[~((scores >= 70) & (scores <= 80))])
# [85 92 58 45 88 63 95]
np.where------条件选择的利器
python
scores = np.array([85, 52, 78, 45, 92, 33, 67])
# np.where(条件, 真时的值, 假时的值)
result = np.where(scores >= 60, '及格', '不及格')
print("成绩判定:", result)
# ['及格' '不及格' '及格' '不及格' '及格' '不及格' '及格']
# 多条件分级
grades = np.where(scores >= 90, 'A',
np.where(scores >= 80, 'B',
np.where(scores >= 70, 'C',
np.where(scores >= 60, 'D', 'F'))))
print("等级:", grades)
# 获取满足条件的索引位置
print("及格的索引:", np.where(scores >= 60)[0])
# [0 2 4 6]
np.select------多条件选择的更优雅写法
python
scores = np.array([95, 82, 73, 58, 45, 88, 67])
# 定义条件列表
conditions = [
scores >= 90,
scores >= 80,
scores >= 70,
scores >= 60
]
# 定义对应的结果
choices = ['优秀', '良好', '中等', '及格']
# np.select 按顺序匹配条件,返回第一个为 True 的对应值
grades = np.select(conditions, choices, default='不及格')
print("成绩等级:", grades)
# ['优秀' '良好' '中等' '不及格' '不及格' '良好' '及格']
实战:数据清洗中的布尔索引
python
# 模拟一份包含异常值的数据
data = np.array([23, 25, 22, 999, 24, 21, -50, 26, 23, 25])
print("原始数据:", data)
# 定义合理范围(假设年龄在 0~120 之间)
valid_mask = (data >= 0) & (data <= 120)
print("有效数据:", data[valid_mask])
# 用中位数替换异常值
median_val = np.median(data[valid_mask])
cleaned = np.where(valid_mask, data, median_val)
print("清洗后数据:", cleaned)
三、维度变换------数据的"变形术"
reshape------改变数组的形状
python
arr = np.arange(12)
print("原始 (12,):", arr)
# 变成 3 行 4 列
reshaped = arr.reshape(3, 4)
print("\nreshape(3,4):\n", reshaped)
# 变成 2 行 3 列 2 层(三维)
reshaped_3d = arr.reshape(2, 3, 2)
print("\nreshape(2,3,2):\n", reshaped_3d)
# 使用 -1 自动计算某个维度
print("\nreshape(4, -1) 自动计算列数:\n", arr.reshape(4, -1))
# -1 表示"自动推算",12/4=3 列
print("reshape(-1, 1) 变成列向量:\n", arr.reshape(-1, 1))
reshape 的规则:新形状的元素总数必须与原数组相同。12 个元素可以变成 (3,4)、(2,6)、(4,3)、(2,2,3) 等,但不能变成 (3,5)(需要 15 个元素)。
ravel 和 flatten------把多维数组拉平
python
matrix = np.array([[1, 2, 3],
[4, 5, 6]])
# ravel 返回视图(共享内存)
print("ravel():", matrix.ravel()) # [1 2 3 4 5 6]
# flatten 返回副本(独立内存)
print("flatten():", matrix.flatten()) # [1 2 3 4 5 6]
# 修改验证
flat_view = matrix.ravel()
flat_view[0] = 99
print("ravel 修改后原数组:", matrix[0, 0]) # 99
flat_copy = matrix.flatten()
flat_copy[0] = 0
print("flatten 修改后原数组:", matrix[0, 0]) # 仍是 99
transpose------转置(行列互换)
python
matrix = np.array([[1, 2, 3],
[4, 5, 6]])
print("原始矩阵:")
print(matrix)
print("\n转置 (matrix.T):")
print(matrix.T)
# [[1 4]
# [2 5]
# [3 6]]
# 另一种写法
print("\nnp.transpose(matrix):")
print(np.transpose(matrix))
swapaxes 和 moveaxis------交换/移动轴
python
# 三维数组
arr_3d = np.arange(24).reshape(2, 3, 4)
print("原始形状:", arr_3d.shape) # (2, 3, 4)
# 交换第 0 轴和第 2 轴
swapped = arr_3d.swapaxes(0, 2)
print("swapaxes(0,2) 后形状:", swapped.shape) # (4, 3, 2)
# 移动轴:把第 2 轴移动到第 0 位置
moved = np.moveaxis(arr_3d, 2, 0)
print("moveaxis(2,0) 后形状:", moved.shape) # (4, 2, 3)
理解 transpose 的参数 :
arr.transpose(2, 0, 1)表示原来第 2 维变成新数组的第 0 维,原来第 0 维变成新数组的第 1 维,原来第 1 维变成新数组的第 2 维。
python
# 详细演示 transpose 的维度变化
arr = np.arange(24).reshape(2, 3, 4)
print("原始形状:", arr.shape) # (2, 3, 4)
# transpose(1, 0, 2): 第1维→新第0维, 第0维→新第1维, 第2维不变
t = arr.transpose(1, 0, 2)
print("transpose(1,0,2) 后形状:", t.shape) # (3, 2, 4)
四、数组的拼接与拆分
拼接(合并数组)
python
a = np.array([[1, 2],
[3, 4]])
b = np.array([[5, 6],
[7, 8]])
# 垂直拼接(按行拼接)
print("vstack (垂直):\n", np.vstack((a, b)))
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
# 水平拼接(按列拼接)
print("\nhstack (水平):\n", np.hstack((a, b)))
# [[1 2 5 6]
# [3 4 7 8]]
# 通用拼接函数
print("\nconcatenate axis=0 (垂直):\n", np.concatenate((a, b), axis=0))
print("concatenate axis=1 (水平):\n", np.concatenate((a, b), axis=1))
# np.column_stack:把一维数组按列拼接
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print("\ncolumn_stack:\n", np.column_stack((x, y)))
# [[1 4]
# [2 5]
# [3 6]]
# np.r_ 和 np.c_(快捷写法)
print("\nnp.r_[a, b] (垂直):\n", np.r_[a, b])
print("np.c_[a, b] (水平):\n", np.c_[a, b])
拆分(分割数组)
python
arr = np.arange(12).reshape(3, 4)
print("原始数组:\n", arr)
# 垂直拆分成 3 份
print("\n垂直拆分 (vsplit):")
parts_v = np.vsplit(arr, 3)
for i, p in enumerate(parts_v):
print(f"第{i}份:\n", p)
# 水平拆分成 2 份
print("\n水平拆分 (hsplit):")
parts_h = np.hsplit(arr, 2)
for i, p in enumerate(parts_h):
print(f"第{i}份:\n", p)
# 按指定位置拆分
print("\n在列索引 [1, 3] 处拆分:")
parts = np.split(arr, [1, 3], axis=1)
for i, p in enumerate(parts):
print(f"第{i}份:\n", p)
五、矩阵运算------线性代数基础
点积(Dot Product)
python
# 向量点积
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print("向量点积 a·b:", np.dot(a, b))
# 1*4 + 2*5 + 3*6 = 32
# 矩阵乘法
A = np.array([[1, 2],
[3, 4]])
B = np.array([[5, 6],
[7, 8]])
print("矩阵乘法 A @ B:")
print(A @ B)
# 或
print(np.dot(A, B))
# 或
print(A.dot(B))
# 结果: [[19 22]
# [43 50]]
# @ 是 Python 3.5+ 引入的矩阵乘法运算符(推荐用法)
print("\n使用 @ 运算符:")
print(A @ B)
重要区别 :
A * B是逐元素相乘,A @ B才是矩阵乘法。
python
print("逐元素相乘 A * B:")
print(A * B)
# [[ 5 12]
# [21 32]]
print("矩阵乘法 A @ B:")
print(A @ B)
# [[19 22]
# [43 50]]
常用线性代数运算
python
matrix = np.array([[1, 2],
[3, 4]])
# 行列式
det = np.linalg.det(matrix)
print(f"行列式: {det:.2f}") # -2.00
# 逆矩阵
inv = np.linalg.inv(matrix)
print("逆矩阵:\n", np.round(inv, 2))
# 验证: A @ A_inv = I
print("验证 A @ A_inv:\n", np.round(matrix @ inv, 10))
# 特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(matrix)
print("特征值:", eigenvalues)
print("特征向量:\n", eigenvectors)
# 矩阵的秩
rank = np.linalg.matrix_rank(matrix)
print("矩阵的秩:", rank)
# 迹(对角线元素之和)
trace = np.trace(matrix)
print("迹:", trace) # 1 + 4 = 5
解线性方程组
python
# 解方程组:
# 2x + 3y = 8
# 4x + y = 6
A = np.array([[2, 3],
[4, 1]])
b = np.array([8, 6])
# 求解 x
solution = np.linalg.solve(A, b)
print(f"方程组的解: x = {solution[0]:.2f}, y = {solution[1]:.2f}")
# 验证
print("验证:", A @ solution) # 应该接近 [8, 6]
最小二乘法拟合
python
# 模拟一组带有噪声的线性数据
np.random.seed(42)
x = np.linspace(0, 10, 20)
y_true = 2 * x + 3 # 真实关系: y = 2x + 3
noise = np.random.normal(0, 3, 20) # 添加噪声
y_noisy = y_true + noise
# 使用最小二乘法拟合
# 构建设计矩阵 [x, 1]
A_fit = np.column_stack([x, np.ones_like(x)])
# 求解
coefficients, residuals, rank, s = np.linalg.lstsq(A_fit, y_noisy, rcond=None)
slope, intercept = coefficients
print(f"拟合结果: y = {slope:.2f}x + {intercept:.2f}")
print(f"真实结果: y = 2.00x + 3.00")
print(f"残差: {residuals[0]:.2f}")
代码示例:综合实战
实战1:电商销售数据分析
python
import numpy as np
np.random.seed(42)
# 模拟一个月的销售数据(30天 x 5个品类)
categories = ['电子产品', '服装', '食品', '家居', '图书']
sales = np.random.randint(1000, 50000, (30, 5))
print("=" * 60)
print("电商月度销售数据分析")
print("=" * 60)
# 1. 各品类月度总销售额
total_by_category = sales.sum(axis=0)
print("\n各品类月度总销售额:")
for i, cat in enumerate(categories):
print(f" {cat}: ¥{total_by_category[i]:,}")
# 2. 找出销售额最低的5天(可能是工作日或淡季)
daily_total = sales.sum(axis=1)
bottom5_days = np.argsort(daily_total)[:5]
print(f"\n销售额最低的5天: 第{bottom5_days + 1}天")
# 3. 找出每个品类销售额最高的3天
print("\n各品类最佳销售日:")
for i, cat in enumerate(categories):
col = sales[:, i]
top3 = np.argsort(col)[-3:][::-1] # 排序后取最后3个并反转
print(f" {cat}: 第{top3 + 1}天 (销售额: {col[top3]})")
# 4. 异常值检测(某品类某天销售额超过均值+2倍标准差)
print("\n异常高销售记录:")
for i, cat in enumerate(categories):
col = sales[:, i]
mean, std = col.mean(), col.std()
threshold = mean + 2 * std
outliers = np.where(col > threshold)[0]
if len(outliers) > 0:
print(f" {cat}: 第{outliers + 1}天 ({col[outliers]}, 阈值={threshold:.0f})")
实战2:图像数据处理
python
import numpy as np
# 模拟一张 28x28 的灰度图像(MNIST 手写数字格式)
np.random.seed(42)
image = np.random.randint(0, 256, (28, 28), dtype=np.uint8)
# 1. 展平为向量(用于机器学习输入)
flat = image.flatten()
print(f"原始形状: {image.shape}")
print(f"展平后: {flat.shape}")
# 2. 裁剪:只保留图像中间 20x20 的区域
cropped = image[4:24, 4:24]
print(f"裁剪后形状: {cropped.shape}")
# 3. 降采样:每隔一行/列取一个值(减半分辨率)
downsampled = image[::2, ::2]
print(f"降采样后形状: {downsampled.shape}")
# 4. 标准化到 [0, 1] 范围
normalized = image.astype(np.float64) / 255.0
print(f"标准化范围: [{normalized.min():.3f}, {normalized.max():.3f}]")
# 5. 数据增强:水平翻转
flipped = np.fliplr(image)
print(f"水平翻转后左上角像素: {flipped[0, 0]} (原右上角: {image[0, -1]})")
# 6. 旋转90度
rotated = np.rot90(image)
print(f"旋转90度后形状: {rotated.shape}")
# 7. 批量处理:假设有100张图像
batch = np.random.randint(0, 256, (100, 28, 28), dtype=np.uint8)
print(f"\n批量图像数据形状: {batch.shape}")
# 批量标准化
batch_norm = batch.astype(np.float64) / 255.0
print(f"批量标准化后范围: [{batch_norm.min():.3f}, {batch_norm.max():.3f}]")
实战3:矩阵运算解决实际问题
python
import numpy as np
# 问题:投资组合优化
# 假设有3种资产,预期收益率和风险(协方差矩阵)如下
expected_returns = np.array([0.08, 0.12, 0.15]) # 年化收益率 8%, 12%, 15%
cov_matrix = np.array([[0.0004, 0.0003, 0.0002],
[0.0003, 0.0009, 0.0004],
[0.0002, 0.0004, 0.0016]])
# 等权重投资组合
weights = np.array([1/3, 1/3, 1/3])
# 组合预期收益
portfolio_return = weights @ expected_returns
print(f"等权重组合预期收益: {portfolio_return*100:.2f}%")
# 组合风险(标准差)
portfolio_risk = np.sqrt(weights @ cov_matrix @ weights)
print(f"等权重组合风险: {portfolio_risk*100:.2f}%")
# 比较不同权重
weight_sets = [
[0.5, 0.3, 0.2],
[0.2, 0.3, 0.5],
[0.1, 0.1, 0.8],
[0.4, 0.4, 0.2]
]
print("\n不同权重配置比较:")
print(f"{'权重':^20} | {'收益率':^8} | {'风险':^8} | {'夏普比率':^8}")
print("-" * 55)
for w in weight_sets:
w = np.array(w)
ret = w @ expected_returns
risk = np.sqrt(w @ cov_matrix @ w)
sharpe = ret / risk if risk > 0 else 0 # 简化夏普比率
print(f"{str(w):^20} | {ret*100:^7.2f}% | {risk*100:^7.2f}% | {sharpe:^8.2f}")
实战练习
练习1:花式索引与布尔索引
题目:创建一个包含 20 个学生成绩的数组,成绩范围 0~100。完成以下操作:
- 提取第 1、5、10、15、20 个学生的成绩
- 找出所有及格(>=60)的学生成绩
- 找出成绩在 70~90 之间的学生成绩
- 将不及格的成绩标记为"补考",及格的标记为"通过"
参考答案:
python
np.random.seed(42)
scores = np.random.randint(0, 101, 20)
print("所有成绩:", scores)
# 1. 提取指定位置
print("指定位置成绩:", scores[[0, 4, 9, 14, 19]])
# 2. 及格学生
print("及格成绩:", scores[scores >= 60])
# 3. 70~90分
print("70~90分:", scores[(scores >= 70) & (scores <= 90)])
# 4. 标记
status = np.where(scores >= 60, '通过', '补考')
for i, (s, st) in enumerate(zip(scores, status)):
print(f" 学生{i+1}: {s}分 - {st}")
练习2:维度变换
题目 :将数组 np.arange(24) 变成以下形状:
- 3 行 8 列的二维数组
- 2 层、3 行、4 列的三维数组
- 24 行 1 列的列向量
- 将三维数组的第 2 维和第 0 维交换
参考答案:
python
arr = np.arange(24)
# 1. 3x8
print("3x8:\n", arr.reshape(3, 8))
# 2. 2x3x4
print("2x3x4:\n", arr.reshape(2, 3, 4))
# 3. 列向量
print("列向量:\n", arr.reshape(-1, 1))
# 4. 交换维度
arr_3d = arr.reshape(2, 3, 4)
swapped = arr_3d.swapaxes(0, 2)
print("交换0和2轴后形状:", swapped.shape) # (4, 3, 2)
练习3:矩阵运算
题目:解以下线性方程组:
x + y + z = 6
2x - y + 3z = 9
3x + 2y - z = 1
参考答案:
python
A = np.array([[1, 1, 1],
[2, -1, 3],
[3, 2, -1]])
b = np.array([6, 9, 1])
solution = np.linalg.solve(A, b)
print(f"解: x={solution[0]:.2f}, y={solution[1]:.2f}, z={solution[2]:.2f}")
# 验证
print("验证:", A @ solution) # 应为 [6, 9, 1]
练习4:综合数据处理
题目:创建一个 100 行 5 列的随机数矩阵(值域 0~100),完成以下任务:
- 每列减去该列的均值(中心化)
- 每列除以该列的标准差(标准化)
- 找出标准化后绝对值大于 2 的异常值位置
- 将异常值替换为该列的中位数
参考答案:
python
np.random.seed(42)
data = np.random.uniform(0, 100, (100, 5))
# 1. 中心化
means = data.mean(axis=0)
centered = data - means
# 2. 标准化
stds = data.std(axis=0)
standardized = centered / stds
# 3. 找异常值(|z| > 2)
outlier_mask = np.abs(standardized) > 2
outlier_positions = np.where(outlier_mask)
print(f"发现 {outlier_positions[0].size} 个异常值")
# 4. 替换为中位数
medians = np.median(data, axis=0)
cleaned = np.where(outlier_mask, medians, data)
# 验证
new_std = (cleaned - cleaned.mean(axis=0)) / cleaned.std(axis=0)
print(f"清洗后最大绝对值: {np.abs(new_std).max():.3f}")
本节总结
本节内容比较丰富,让我们回顾核心要点:
- 花式索引:用整数数组索引,灵活提取任意位置的元素。记住它返回的是副本,不是视图。
- 布尔索引 :用条件表达式筛选数据,是数据清洗和分析中最常用的技术之一。配合
np.where和np.select使用效果更佳。 - 维度变换 :
reshape:改变形状,元素总数不变transpose/.T:行列互换swapaxes/moveaxis:交换或移动特定维度flattenvsravel:一个返回副本,一个返回视图
- 拼接与拆分 :
vstack/hstack/concatenate用于合并,vsplit/hsplit/split用于分割。 - 矩阵运算 :
@是矩阵乘法,*是逐元素乘法。np.linalg模块提供行列式、逆矩阵、特征值、解方程等线性代数功能。
核心思维转变:本节最重要的不是记住每个函数的用法,而是建立"向量化思维"------遇到问题时,首先想"如何用数组操作代替循环",而不是"如何用 for 循环逐个处理"。这种思维方式是高效数据分析的核心。
下一节预告
你已经学会了 NumPy 的索引和维度变换,但还有一个关键问题:你的代码真的够快吗?
在第4节中,我们将深入探讨 NumPy 向量化运算------如何用向量化的方式替换所有 for 循环,让代码速度提升 100 倍甚至 1000 倍。你将学习:
- 什么是向量化,为什么它这么快
- ufunc(通用函数)的深入理解
np.where和np.select的高级用法- 实际性能对比实验,亲眼见证速度差异
准备好让你的代码飞起来了吗?
结尾
希望对初学者有帮助;致力于办公自动化的小小程序员一枚
希望能得到大家的【❤️一个免费关注❤️】感谢!
求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍
此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏
此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏
此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏