第3节:从表格到矩阵——NumPy 高级索引与维度变换实战

目录

专栏导读

🌸 欢迎来到Python办公自动化专栏---Python处理办公问题,解放您的双手
🏳️‍🌈 个人博客主页:请点击------> 个人的博客主页 求收藏
🏳️‍🌈 Github主页:请点击------> Github主页 求Star⭐
🏳️‍🌈 知乎主页:请点击------> 知乎主页 求关注
🏳️‍🌈 CSDN博客主页:请点击------> CSDN的博客主页 求关注
👍 该系列文章专栏:请点击------>Python办公自动化专栏 求订阅
🕷 此外还有爬虫专栏:请点击------>Python爬虫基础专栏 求订阅
📕 此外还有python基础专栏:请点击------>Python基础学习专栏 求订阅
文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
❤️ 欢迎各位佬关注! ❤️

第3节:从表格到矩阵------NumPy 高级索引与维度变换实战

本节学习目标

完成本节学习后,你将能够:

  1. 掌握花式索引(Fancy Indexing),用索引数组提取任意位置的元素
  2. 熟练使用布尔索引进行条件筛选
  3. 理解并运用 reshape、transpose、swapaxes 等维度变换操作
  4. 掌握数组的拼接(concatenate/stack)和拆分(split)
  5. 了解基本的矩阵运算(点积、逆矩阵、行列式等)
  6. 综合运用高级技巧解决实际数据处理问题

为什么学这个

想象一下,你面前有一张包含 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. 提取第 1、5、10、15、20 个学生的成绩
  2. 找出所有及格(>=60)的学生成绩
  3. 找出成绩在 70~90 之间的学生成绩
  4. 将不及格的成绩标记为"补考",及格的标记为"通过"

参考答案

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) 变成以下形状:

  1. 3 行 8 列的二维数组
  2. 2 层、3 行、4 列的三维数组
  3. 24 行 1 列的列向量
  4. 将三维数组的第 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),完成以下任务:

  1. 每列减去该列的均值(中心化)
  2. 每列除以该列的标准差(标准化)
  3. 找出标准化后绝对值大于 2 的异常值位置
  4. 将异常值替换为该列的中位数

参考答案

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

本节总结

本节内容比较丰富,让我们回顾核心要点:

  1. 花式索引:用整数数组索引,灵活提取任意位置的元素。记住它返回的是副本,不是视图。
  2. 布尔索引 :用条件表达式筛选数据,是数据清洗和分析中最常用的技术之一。配合 np.wherenp.select 使用效果更佳。
  3. 维度变换
    • reshape:改变形状,元素总数不变
    • transpose / .T:行列互换
    • swapaxes / moveaxis:交换或移动特定维度
    • flatten vs ravel:一个返回副本,一个返回视图
  4. 拼接与拆分vstack/hstack/concatenate 用于合并,vsplit/hsplit/split 用于分割。
  5. 矩阵运算@ 是矩阵乘法,* 是逐元素乘法。np.linalg 模块提供行列式、逆矩阵、特征值、解方程等线性代数功能。

核心思维转变:本节最重要的不是记住每个函数的用法,而是建立"向量化思维"------遇到问题时,首先想"如何用数组操作代替循环",而不是"如何用 for 循环逐个处理"。这种思维方式是高效数据分析的核心。


下一节预告

你已经学会了 NumPy 的索引和维度变换,但还有一个关键问题:你的代码真的够快吗?

在第4节中,我们将深入探讨 NumPy 向量化运算------如何用向量化的方式替换所有 for 循环,让代码速度提升 100 倍甚至 1000 倍。你将学习:

  • 什么是向量化,为什么它这么快
  • ufunc(通用函数)的深入理解
  • np.wherenp.select 的高级用法
  • 实际性能对比实验,亲眼见证速度差异

准备好让你的代码飞起来了吗?

结尾

希望对初学者有帮助;致力于办公自动化的小小程序员一枚
希望能得到大家的【❤️一个免费关注❤️】感谢!
求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍
此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏
此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏
此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏
相关推荐
图码3 小时前
矩阵数据结构入门指南:声明、初始化与基本操作
运维·数据结构·线性代数·算法·矩阵
我是大聪明.7 小时前
Attention机制的数学本质:从Softmax到FlashAttention的演进
线性代数·矩阵
XX風1 天前
三维点云处理环境相关-ubuntu安装numpy、open3d
linux·ubuntu·numpy
我是大聪明.1 天前
大模型Tokenizer原理:BPE、WordPiece与子词编码的核心机制深度解析
人工智能·线性代数·算法·机器学习·矩阵
xin_nai1 天前
LeetCode热题100(Java)(6)矩阵
java·leetcode·矩阵
方安乐2 天前
python之向量、向量和、向量点积
开发语言·python·numpy
隔壁大炮2 天前
Day07-RNN介绍
人工智能·pytorch·rnn·深度学习·神经网络·算法·numpy
萌新小码农‍2 天前
人工智能线性代数基础
人工智能·线性代数·机器学习
生信研究猿2 天前
#P4538.第2题-基于混淆矩阵,推导分类模型的核心评估指标
线性代数·矩阵