numpy中的reshape() 专题教学(详细教学版)
文章目录
- 前言
- 一、先从 `shape` 开始:什么叫“形状”?
- 二、`reshape()` 到底在干什么?
- 三、为什么 `(2, 3)` 可以,但 `(2, 4)` 不可以?
- 四、`-1` 到底是什么意思?
- 五、再看一个:`reshape(-1, 2)` 是什么意思?
- 六、`reshape(2, -1)` 又是什么意思?
- 七、为什么 `-1` 很常用?
- 八、`reshape()` 里为什么有时候是两个参数?
- 九、`reshape()` 里为什么有时候是三个参数?
- 十、为什么机器学习里经常“先拉平,再 reshape 回去”?
- 十一、为什么这里拉平成 `(-1, 4)`?
- 十二、为什么 `reshape(-1, 1)` 和 `reshape(1, -1)` 完全不同?
- 十三、为什么线性回归里经常写 `reshape(-1, 1)`?
- 十四、为什么 RNN / LSTM 题里常写 `reshape(-1, 5, 8)`?
- 十五、`reshape()` 最常见的报错原因是什么?
- 十六、你应该怎么判断 reshape 写得对不对?
- 十七、最短记忆版
- 十八、课堂追问
- 总结
前言
这份文件讲什么?
这是一份专门给代码基础很弱的学生准备的 reshape() 教学文件。
它重点解决这些最常见的问题:
shape到底是什么意思reshape()到底在干什么-1到底是什么意思- 为什么有时候写两个参数,有时候写三个参数
- 为什么机器学习里总是先
reshape再标准化、再reshape回去 reshape(-1, 1)、reshape(1, -1)、reshape(-1, 4)、reshape(-1, 5, 8)分别是什么意思
这份 notebook 的目标不是让你“背语法”,而是让你真正理解:
数组只是换了排布方式,总元素个数并没有变。
一、先从 shape 开始:什么叫“形状”?
在 NumPy 里,每个数组都有一个 shape,表示:
这个数组现在是按什么结构排布的
例如:
(6,)表示一维数组,一共有 6 个元素(2, 3)表示二维数组,2 行 3 列(2, 3, 4)表示三维数组,可以理解成有 2 个块,每个块里是 3 行 4 列
重点提醒
shape 不是在说数组“值是多少”,而是在说:
这些值现在是怎么摆放的
import numpy as np
x = np.array([1, 2, 3, 4, 5, 6])
print("x =")
print(x)
print("x.shape =", x.shape)
二、reshape() 到底在干什么?
reshape() 的作用是:
不改变元素总个数,只改变这些元素的排布方式
例如,原来是一维数组:
[1, 2, 3, 4, 5, 6]
你可以把它改成二维数组:
[[1, 2, 3],
[4, 5, 6]]
虽然长得不一样,但里面的 6 个数字还是同样那 6 个数字。
最重要的规则
reshape() 前后,总元素个数必须一样。
x_2d = x.reshape(2, 3)
print("x.reshape(2, 3) =")
print(x_2d)
print("shape =", x_2d.shape)
三、为什么 (2, 3) 可以,但 (2, 4) 不可以?
因为原数组里一共只有 6 个元素。
如果写:
reshape(2, 3)
表示:
- 2 行
- 3 列
总共需要:
2 * 3 = 6
正好对得上。
如果写:
reshape(2, 4)
表示:
- 2 行
- 4 列
总共需要:
2 * 4 = 8
但原数组只有 6 个元素,所以不行。
print("原数组元素总数 =", x.size)
print("\n可以的例子:reshape(3, 2)")
print(x.reshape(3, 2))
print("\n不可以的例子:reshape(2, 4)")
try:
print(x.reshape(2, 4))
except Exception as e:
print("报错信息:", e)
四、-1 到底是什么意思?
-1 的意思是:
这一维我不手工算了,让 NumPy 自动帮我算
例如:
x.reshape(-1, 1)
意思是:
- 列数固定为 1
- 行数让 NumPy 自动算
因为原数组一共有 6 个元素,所以 NumPy 会自动算出:
- 6 行
- 1 列
所以结果 shape 是 (6, 1)。
x_col = x.reshape(-1, 1)
print("x.reshape(-1, 1) =")
print(x_col)
print("shape =", x_col.shape)
五、再看一个:reshape(-1, 2) 是什么意思?
x.reshape(-1, 2)
意思是:
- 每行 2 个元素
- 一共多少行让 NumPy 自动算
因为总共有 6 个元素,所以会自动算出:
- 3 行
- 2 列
也就是 shape = (3, 2)
x_3_2 = x.reshape(-1, 2)
print("x.reshape(-1, 2) =")
print(x_3_2)
print("shape =", x_3_2.shape)
六、reshape(2, -1) 又是什么意思?
这次反过来:
x.reshape(2, -1)
意思是:
- 行数固定 2
- 列数让 NumPy 自动算
因为总共有 6 个元素,分成 2 行后,每行就必须有 3 个元素。
所以结果 shape 是 (2, 3)。
x_2_auto = x.reshape(2, -1)
print("x.reshape(2, -1) =")
print(x_2_auto)
print("shape =", x_2_auto.shape)
七、为什么 -1 很常用?
因为很多时候你只知道:
- 我希望每行有几个特征
- 但我不想自己去手工算一共有多少行
这时就可以写 -1。
例如:
reshape(-1, 4)
意思就是:
- 每行有 4 个特征
- 一共有多少行,NumPy 自动算
这在机器学习里特别常见。
八、reshape() 里为什么有时候是两个参数?
当你写:
reshape(a, b)
你是在把数组变成二维。
二维数组最常见的理解方式是:
- 第 1 维:行数
- 第 2 维:列数
在机器学习里,二维数组经常表示:
(样本数, 特征数)
例如:
(100, 2):100 个样本,每个样本 2 个特征(640, 8):640 个样本,每个样本 8 个特征
a = np.arange(12)
print("原数组 a =")
print(a)
print("a.shape =", a.shape)
a_2d = a.reshape(3, 4)
print("\na.reshape(3, 4) =")
print(a_2d)
print("shape =", a_2d.shape)
九、reshape() 里为什么有时候是三个参数?
当你写:
reshape(a, b, c)
你是在把数组变成三维。
三维数组在机器学习里很常见于:
- 时序数据
- 视频数据
- 多通道信号
- 批量图像
时序数据最常见的写法
(样本数, 时间步, 特征数)
例如:
(640, 5, 8)表示:- 640 个样本
- 每个样本 5 个时间步
- 每个时间步 8 个特征
b = np.arange(24)
b_3d = b.reshape(2, 3, 4)
print("b.reshape(2, 3, 4) =")
print(b_3d)
print("shape =", b_3d.shape)
十、为什么机器学习里经常“先拉平,再 reshape 回去”?
这和很多作业题非常相关。
例如,原始输入可能是时序数据:
(样本数, 时间步, 特征数)
但像 StandardScaler() 这样的工具通常要求输入是二维:
(样本数, 特征数)
所以常见流程是:
第一步:先把三维拉平成二维
比如:
X.reshape(-1, 8)
第二步:做标准化
scaler.fit_transform(...)
第三步:再 reshape 回三维
比如:
.reshape(-1, 5, 8)
这就是为什么很多时序题里你会看到一连串 reshape。
X_demo = np.arange(80).reshape(2, 10, 4)
print("原始三维数据 X_demo.shape =", X_demo.shape)
X_flat = X_demo.reshape(-1, 4)
print("拉平成二维后 X_flat.shape =", X_flat.shape)
X_back = X_flat.reshape(-1, 10, 4)
print("再变回三维后 X_back.shape =", X_back.shape)
十一、为什么这里拉平成 (-1, 4)?
因为原来三维数据的最后一维是 4,表示:
每个时间步有 4 个特征
我们做标准化时,仍然希望:
- 每一列对应一个固定特征
- 不要把特征混乱掉
所以 reshape 成:
(-1, 4)
意思就是:
- 前面样本数和时间步数先合并
- 每一行保留 4 个特征
这样标准化器就能“按列处理每个特征”。
十二、为什么 reshape(-1, 1) 和 reshape(1, -1) 完全不同?
这两个虽然都用了 -1,但意思完全不一样。
reshape(-1, 1)
表示:
- 变成一列
- 行数自动算
结果像这样:
[[1],
[2],
[3],
[4]]
shape 是 (4, 1)
reshape(1, -1)
表示:
- 变成一行
- 列数自动算
结果像这样:
[[1, 2, 3, 4]]
shape 是 (1, 4)
c = np.array([1, 2, 3, 4])
print("c.reshape(-1, 1) =")
print(c.reshape(-1, 1))
print("shape =", c.reshape(-1, 1).shape)
print("\nc.reshape(1, -1) =")
print(c.reshape(1, -1))
print("shape =", c.reshape(1, -1).shape)
十三、为什么线性回归里经常写 reshape(-1, 1)?
因为很多 sklearn 模型要求输入 X 必须是二维。
如果只有一个特征,例如:
x = [1, 2, 3, 4]
它原本 shape 是:
(4,)
这是一个一维数组。
但模型想要的是:
(4, 1)
意思是:
- 4 个样本
- 每个样本 1 个特征
所以就常写:
x.reshape(-1, 1)
x_lin = np.array([1, 2, 3, 4])
print("原 shape =", x_lin.shape)
print("reshape(-1, 1) 后 shape =", x_lin.reshape(-1, 1).shape)
print(x_lin.reshape(-1, 1))
十四、为什么 RNN / LSTM 题里常写 reshape(-1, 5, 8)?
因为 RNN / LSTM 读的是三维时序数据。
例如:
(样本数, 时间步, 特征数)
如果题目规定:
- 每个样本 5 个时间步
- 每个时间步 8 个特征
那么最终喂给 LSTM 的 shape 就应该是:
(-1, 5, 8)
这里的 -1 表示:
- 有多少个样本,让 NumPy 自动算
z = np.arange(160)
z_seq = z.reshape(-1, 5, 8)
print("z.reshape(-1, 5, 8) 后 shape =", z_seq.shape)
print("也就是:样本数自动算,每个样本 5 个时间步,每步 8 个特征")
十五、reshape() 最常见的报错原因是什么?
1. 总元素个数对不上
例如原来只有 6 个元素,却想 reshape 成 (2, 4),这是不行的。
2. 同时写了两个 -1
例如:
reshape(-1, -1)
这是不行的,因为 NumPy 不知道该自动算哪一维。
3. 逻辑上 shape 虽然对,但语义不对
例如本来最后一维是“特征数”,你却写错成别的数,虽然总元素个数对得上,但机器学习意义错了。
print("错误示例 1:元素数对不上")
try:
print(np.arange(6).reshape(2, 4))
except Exception as e:
print("报错:", e)
print("\n错误示例 2:同时写两个 -1")
try:
print(np.arange(6).reshape(-1, -1))
except Exception as e:
print("报错:", e)
十六、你应该怎么判断 reshape 写得对不对?
以后遇到 reshape,不要死记,直接问自己这 4 个问题:
1. 原数组一共有多少个元素?
先看 .size
2. 你想变成几维?
- 二维?
- 三维?
3. 每一维在机器学习里代表什么?
例如:
- 样本数
- 时间步数
- 特征数
4. reshape 前后,总元素个数是否一致?
这是硬性要求。
demo = np.arange(24)
print("demo.size =", demo.size)
print("demo.reshape(2, 3, 4).shape =", demo.reshape(2, 3, 4).shape)
print("2 * 3 * 4 =", 2 * 3 * 4)
十七、最短记忆版
你可以记住下面几句:
reshape():改形状,不改总元素个数-1:这一维让 NumPy 自动算reshape(-1, 1):变成一列reshape(1, -1):变成一行reshape(-1, 4):二维,每行 4 个特征reshape(-1, 5, 8):三维,每个样本 5 个时间步、每步 8 个特征
十八、课堂追问
reshape()会不会改变数组里的数字?- 为什么
reshape()前后元素总数必须一致? -1到底是什么意思?reshape(-1, 1)和reshape(1, -1)有什么区别?- 为什么
StandardScaler()前常常先把三维数据拉平成二维? - 为什么 RNN / LSTM 的输入通常是三维数组?
- 如果原数组有 80 个元素,写
reshape(-1, 10, 4)时,NumPy 会自动算出多少个样本?
总结
本文从零开始,系统讲解了 NumPy 中 reshape() 函数的用法,重点解决了以下几个核心概念:
- shape(形状):只是元素的排列方式,不改变元素本身。
- reshape 规则:元素总数必须前后一致,否则会报错。
-1的含义:让 NumPy 自动推算这一维的大小,极大简化了代码。- 二维与三维:分别对应
(样本数, 特征数)和(样本数, 时间步, 特征数)的典型机器学习数据格式。 - 典型应用:将一维特征转为二维供 sklearn 使用
reshape(-1,1);标准化前将时序数据拉平成二维,处理完再还原;构建 LSTM 输入时用reshape(-1, time_steps, features)。
理解这些基础后,再遇到任何 reshape 都不会慌张。记住的关键一句话:reshape 只是换种摆法,数字一个不少。
最后,不妨尝试回答文中十八个课堂追问,检验一下自己是否真的掌握了 reshape 的精髓。
更多推荐

所有评论(0)