Python技术迷

numpy如何将一维数组变为二维

这个“numpy一维转二维”的面试题,看着简单,但其实坑不少

面试官问这个问题,八成不是想看你会不会 reshape,而是想看看你对 numpy 的理解到底到啥程度,是不是那种只会 copy paste 的初学者,还是能把维度搞清楚、真能用 numpy 写高性能代码的那种人。

最基础的写法,肯定是这个:

import numpy as np

a = np.array([1, 2, 3, 4, 5, 6])
b = a.reshape((2, 3))  # 转成 2 行 3 列

这代码能跑,结果也对,但你问问自己:你真的知道 reshape 是怎么工作的?你知道 reshape 是浅拷贝还是深拷贝吗?你知道它什么时候会失败吗?

如果你答不出来,那我跟你说,这玩意儿是个大坑。

reshape 背后其实是个视图操作,也就是说它通常不会真的重新分配内存,而是改个“眼镜”换个角度去看那块内存数据。也就是说,它返回的是原数组的一个 view(如果可能的话)。你改了 b 的值,a 的值也可能跟着变。这就像你租了个房子,家具不能换,墙能刷,你换了布局,原房东还是有感觉的。

比如:

b[0][0] = 999
print(a)  # 原数组 a 的第一个值也变成了 999

所以,如果你 reshape 后拿去当新的数据处理,一不小心改了原数组,可能线上直接炸 💥。

还有,面试官喜欢问:“如果 reshape 不符合原数组元素个数,会怎样?”这个你答不上来,那可就露怯了:

a = np.array([1, 2, 3, 4, 5])
a.reshape((2, 3))  # 会直接报错:无法 reshape 成不匹配的形状

记住:reshape 要求新 shape 的元素个数必须和原数组一致,否则就直接 raise 异常,不给你机会蒙混过关。

那是不是 reshape 就是唯一解法了?当然不是!

我们搞 Python 的,手段多了去了,比如你还可以用 np.newaxis 或者 None 来增加维度。

a = np.array([1, 2, 3])
b = a[:, np.newaxis]  # 变成 (3,1),即三行一列
c = a[np.newaxis, :]  # 变成 (1,3),即一行三列

这写法有啥好处?可读性强,而且是明确地告诉 numpy “我就是想在这里加个轴”。不像 reshape 看起来像黑魔法似的(其实它也不黑,就是太灵活了),这种写法一眼就能看出来你要干嘛,团队合作时别人也容易读懂。

特别是你搞神经网络那一挂的,这种写法常常见,比如你要在 batch 维度上加个维度来喂给模型:

# 假设你有个图像的灰度数组 (28,28)
image = np.random.rand(28, 28)
# 加个 batch 维度
image = image[np.newaxis, ...]  # shape 变成 (1,28,28)

还有个骚操作是 reshape(-1, n) 或者 reshape(n, -1),这个 -1 啥意思?老 numpy 用户都懂,它就是自动帮你计算另一边的维度数。

a = np.array([1, 2, 3, 4, 5, 6])
a.reshape(-1, 2)  # 会自动推导出 3 行 2 列

这种写法面试时经常被问:“你能解释 reshape(-1, 2) 的含义吗?”你得答上来:-1 是一个自动计算的标志位,告诉 numpy 自己算一算这个维度填几就对了。

说实话,我还真遇到过有面试官问我 reshape 和 resize 有啥区别。这俩看着像兄弟,其实性格完全不同。reshape 是那种“我不多事,尽量复用原内存”,resize 就像那种“我不管了,直接开新空间重新分配”。

比如:

a = np.array([1, 2, 3])
a.resize((2, 3))  # 会填充 0 或抛异常

这个方法修改的是原数组本身,不像 reshape 那样生成新数组,有些项目里禁止用 resize,因为它副作用太大。

当然啦,你真要写生产代码,reshape 其实不是最关键的,关键是你对 numpy 的 memory model、广播机制、维度规则这些有没有搞懂。写得再花哨,内存拷贝太多了,最后上线一个 batch 就 OOM,那你还不如手撸 for 循环来得实在 😅。

最后说个面试场上我真遇到过的情况:

面试官:“你能用 numpy 把一维数组变成二维数组,同时保证是行向量吗?”

这时候你就得反问一句:“请问是 (1,n) 的那种 row vector,还是 (n,1) 的 column vector?”

如果他说要 row vector,你就这样搞:

a.reshape((1, -1))
# 或者 a[np.newaxis, :]

如果是 column vector,那就:

a.reshape((-1, 1))
# 或者 a[:, np.newaxis]

你看,面试不是考你 API 多熟,是看你脑子清不清楚。你要是答了个 .reshape(2,3) 然后完事,面试官心里都在打分:这人可能就会照搬,理解力一般。

总之啊,这种“看起来很基础”的 numpy 面试题,才是最容易出乱子的地方。你如果理解不到位,面试一慌张就露馅了;反过来,如果你讲得头头是道、还带点实战经验和性能考量,面试官一般都能看出来你是练家子。

-END-

我为大家打造了一份RPA教程,完全免费:https://www.songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领