如果不懂Numpy,请别说自己是Python程序员
昨晚加班到十点多,在工位上喝着冷掉的咖啡,突然听到隔壁工位的小李跟人吹牛:“我写 Python 好几年了,NumPy 也就用过几次,不重要。”我当时差点没忍住笑出来。说真的,如果你还在说“NumPy 不重要”,那基本上就是在自我暴露:你对 Python 的理解还停留在“脚本语言”层面。今天我就想聊聊,为什么不懂 NumPy,就别急着喊自己是 Python 程序员。
Python 的灵魂之一:NumPy
Python 火起来,一半是因为生态,一半是因为科学计算。你看,NumPy 就是 Python 科学计算的基石。所有高阶库,像 Pandas、TensorFlow、PyTorch,甚至 OpenCV,都在底层依赖 NumPy。它其实就是 Python 和 C 语言的桥梁,把数学运算跑到 C 层实现,速度快得飞起。
比如你平时写个 for 循环,求个平方和,可能还洋洋自得,写成这样:
nums = [i for i in range(1, 1000000)]
s = 0
for n in nums:
s += n * n
print(s)
这玩意儿跑下来要几百毫秒。但换成 NumPy,瞬间不一样:
import numpy as nparr = np.arange(1, 1000000)
s = np.sum(arr ** 2)
print(s)
时间差别不是一点点,可能快几十倍。你要说你是 Python 程序员,却还用循环去写这种东西,那就好比开着电动车还在用脚蹬,累不累?
你以为的“数组”和真正的 ndarray
小白刚开始接触 NumPy,会觉得“哎呀不就是个数组库嘛”,其实完全不是一个量级的。Python 自带的 list,底层是链表式存储,每个元素都是对象引用,占空间大,查找效率低。NumPy 的 ndarray,底层就是一块连续的内存,直接存储数值,和 C 语言数组一样紧凑。
这也是为什么 NumPy 支持所谓的“广播机制”。比如一个二维矩阵加一个标量,你不用写循环,它直接帮你扩展计算:
a = np.array([[1, 2, 3],
[4, 5, 6]])
b = 10
print(a + b)
输出就是:
[[11 12 13]
[14 15 16]]
要是用 list,你得写两层循环手动加,这效率差距就一眼能看出来。
为什么工程里少不了它
说个实际场景。前两天我在写一个日志分析工具,要统计日志里的响应时间分布。普通写法,先用正则抽数据,再 list 存储,再算平均值、方差。写了几十行代码。后来一想,这不就是 NumPy 的强项吗?换成 NumPy:
import numpy as nptimes = np.array([12, 15, 20, 11, 17, 19, 21])
print("平均:", np.mean(times))
print("方差:", np.var(times))
print("中位数:", np.median(times))
三行搞定,结果比我写的还准确。再配合 matplotlib 画图,立马就能出个直方图。
你要是不会 NumPy,写数据处理代码就是跟自己过不去。别忘了,数据分析、机器学习、图像处理,甚至金融建模,全都绕不开 NumPy。
初学者常掉的坑
这几年带新人,我发现有几个典型的误区:
当 list 用:很多人把 NumPy array 当 list 去 append、pop,结果发现报错。其实 array 的大小是固定的,你要加元素得用
np.concatenate或者预分配。没搞懂广播:比如一个
(3,1)的矩阵加一个(1,3)的矩阵,结果直接得到(3,3),不少人一脸懵。其实这就是 NumPy 自动扩展维度的规则。混用 list 和 ndarray:有的人
arr = np.array([1, 2, 3]),后面还写arr + [4, 5, 6],结果出来的结果和预期不符。因为 list 运算和 ndarray 运算规则完全不同。
工程级的威力
我上个月在做一个小型推荐系统实验,需要处理几百万条用户行为记录。如果不用 NumPy,光循环就能把人卡死。后来我用 np.dot 写了矩阵乘法,几行代码就把协同过滤的核心搞定了。
# 用户-物品矩阵
user_item = np.array([[5, 3, 0],
[4, 0, 0],
[1, 1, 0],
[0, 0, 5],
[0, 0, 4]])# 物品相似度矩阵
similarity = np.dot(user_item.T, user_item)
print(similarity)
这个结果就能直接拿去算推荐分数,效率高到爆炸。要是手写三层循环,你估计写完都下班了。
NumPy 是 Python 程序员的底线
我经常说一句话:NumPy 是 Python 程序员的底线。为什么?因为它不仅仅是个库,它是整个 Python 数据计算生态的根基。不会 NumPy,就像 Java 程序员不会集合框架,C++ 程序员不会 STL,几乎寸步难行。
而且 NumPy 的 API 并不难学,学会几个核心函数:array、reshape、sum、mean、dot、where,再加上切片和广播,就能覆盖 80% 的场景。剩下的东西,等你真遇到了再查文档就好。
写这篇的时候,我脑子里一直回荡着小李那句“NumPy 不重要”。其实这不是小李一个人的问题,很多人写 Python 写了几年,却一直停留在写脚本、写接口的层面。你要真想说自己是 Python 程序员,就得把 NumPy 至少吃个七八分。
不然,下次别人问你:“数据处理用什么写?”你要是还在 list 里 while 循环,那我劝你还是先把简历上的“精通 Python”删了,免得面试官笑出声。
写个扩展练习题:用 NumPy 模拟 100 万个随机投骰子的结果,统计每个点数出现的概率。你写出来,才算是真正踏进 NumPy 的大门。
import numpy as np# 模拟 100 万次投骰子
rolls = np.random.randint(1, 7, size=1000000)
# 统计频率
counts = np.bincount(rolls)[1:] # 忽略0
probs = counts / rolls.size
print("点数出现的概率:", probs)
这就是 Python 的真正魅力:简洁、强大、优雅。不会 NumPy,真的别急着喊自己是 Python 程序员。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领