机器学习之NumPy 到底是什么?一篇讲透数据处理的 “加速器”
Hello!这里是程序员 Feri—— 13 年 + 开发经验、带过团队、创过业,专注分享编程知识干货。
感谢你的关注与交流,愿我们能相伴你的编程路。
如果你刚接触 Python 数据处理,肯定听过一个名字——NumPy。有人说“学数据分析先学 NumPy”,有人说“用 Python 算数据离不开它”。到底 NumPy 是个啥?为什么这么重要?
今天这篇文章,用大白话+简单代码,带新手彻底搞懂 NumPy,看完就能上手用。

一、先搞明白:为啥需要 NumPy?
咱们先从一个问题开始:Python 本身有列表(list),能存数据、做运算,为啥还要额外学 NumPy?
举个例子:如果你有两个列表 a = [1,2,3] 和 b = [4,5,6],想让它们对应元素相加(1+4,2+5,3+6),用 Python 列表得写循环:
a = [1,2,3]
b = [4,5,6]
c = [a[i]+b[i] for i in range(3)] # 得写循环才敢相加
print(c) # 结果 [5,7,9]
但用 NumPy,一句话就行:
import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
c = a + b # 直接加,不用循环
print(c) # 结果 [5 7 9]
这就是 NumPy 的核心优势:处理数据更快、代码更简单。它就像给 Python 装了个“数据加速器”——不管是算加减乘除,还是处理几万、几十万条数据,都比纯 Python 快得多。
简单说:NumPy 是 Python 里专门用来高效处理数值数据的库,尤其是多维数据(比如表格、矩阵),是 Pandas、Matplotlib 这些常用库的“底层基础”。学会它,后续学数据分析、机器学习会轻松很多。
二、第一步:3分钟装好 NumPy
安装超简单,和装 Matplotlib 差不多,选一种方式就行:
1. 用 pip 安装(大多数人用这个)
打开“命令提示符”(Windows)或“终端”(Mac/Linux),输入:
pip install numpy
2. 用 conda 安装(Anaconda 用户专属)
如果你的 Python 是用 Anaconda 装的,输入:
conda install numpy
3. 验证是否装成功
打开 Python 或 Jupyter Notebook,输入两行代码:
import numpy as np # 引入NumPy,习惯简写成np
print(np.__version__) # 打印版本号,比如 1.26.0
没报错、能看到版本号,就说明装好了!
三、NumPy 的“灵魂”:ndarray 数组
NumPy 的核心是 ndarray(N维数组)——可以理解成“规整的收纳盒”,和 Python 列表(像“杂乱的抽屉”)完全不同。
比如 Python 列表可以混着放数据:[1, "a", True],但 ndarray 里的元素必须是同一种类型(比如全是数字),正因为这种“规整”,它运算起来才快。
1. 怎么创建 ndarray?5种常用方法
创建数组是第一步,这5种方法覆盖了90%的场景,记下来就行:
(1)从 Python 列表创建:np.array()
最常用的方式,把列表“转成”ndarray:
import numpy as np
# 1维数组(像一条线)
arr1 = np.array([1, 2, 3, 4])
print(arr1) # 输出 [1 2 3 4]
# 2维数组(像一张表,2行3列)
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)
# 输出:
# [[1 2 3]
# [4 5 6]]
(2)创建全零/全一数组:np.zeros() / np.ones()
需要初始化一个数组,全是0或1时用,比如创建2行2列的全零数组:
# 全零数组
zero_arr = np.zeros((2, 2)) # 参数是形状 (行数, 列数)
print(zero_arr)
# 输出:
# [[0. 0.]
# [0. 0.]]
# 全一数组
one_arr = np.ones((3, 1)) # 3行1列
print(one_arr)
# 输出:
# [[1.]
# [1.]
# [1.]]
(3)创建连续数字数组:np.arange()
类似 Python 的 range(),但返回的是 ndarray,用着更方便:
# 从0到4(不包含5),步长1
arr = np.arange(0, 5, 1)
print(arr) # 输出 [0 1 2 3 4]
# 从2到10,步长2
arr2 = np.arange(2, 11, 2)
print(arr2) # 输出 [ 2 4 6 8 10]
(4)创建“等分”数组:np.linspace()
比如想把0到10分成5个等份,用这个方法:
# 从0到10,分成5个点(包含10)
arr = np.linspace(0, 10, 5)
print(arr) # 输出 [ 0. 2.5 5. 7.5 10. ]
适合需要“均匀间隔”数据的场景,比如画函数曲线。
(5)创建空数组:np.empty()
创建一个“空”数组(其实是随机值,因为没初始化),适合后续填充数据:
empty_arr = np.empty((2, 3)) # 2行3列
print(empty_arr)
# 输出(值是随机的,每次运行可能不一样):
# [[1. 2. 3.]
# [4. 5. 6.]]
2. 数组的“身份证”:4个关键属性
拿到一个数组,想知道它的“基本信息”,看这4个属性就够了:
| 属性名 | 含义 | 例子(用 arr2 = np.array([[1,2,3],[4,5,6]])) |
|---|---|---|
| ndim | 维度数 | arr2.ndim → 2(2维数组) |
| shape | 形状(行数, 列数) | arr2.shape → (2, 3)(2行3列) |
| size | 元素总数 | arr2.size → 6(2×3=6个元素) |
| dtype | 元素数据类型 | arr2.dtype → int64(64位整数) |
代码演示:
arr2 = np.array([[1,2,3],[4,5,6]])
print("维度数:", arr2.ndim) # 输出 2
print("形状:", arr2.shape) # 输出 (2, 3)
print("元素总数:", arr2.size) # 输出 6
print("数据类型:", arr2.dtype)# 输出 int64
四、NumPy 核心操作:数据怎么用?
创建好数组后,就是对数据进行操作——运算、取数、改形状,这些操作是日常用得最多的。
1. 基本运算:不用循环,直接算
NumPy 支持“向量化操作”,也就是数组之间直接加减乘除,不用写 for 循环,又快又方便。
(1)数组和数字运算
arr = np.array([1, 2, 3])
print(arr + 2) # 每个元素都加2 → [3 4 5]
print(arr * 3) # 每个元素都乘3 → [3 6 9]
print(arr / 2) # 每个元素都除以2 → [0.5 1. 1.5]
(2)两个数组运算
只要形状匹配,就能对应元素运算:
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
print(arr1 + arr2) # 对应元素加 → [5 7 9]
print(arr1 * arr2) # 对应元素乘 → [ 4 10 18]
2. 取数:索引和切片
和 Python 列表类似,但多维数组的取数更灵活,比如从2维数组里取某一行、某一列。
(1)1维数组:和列表一样
arr = np.arange(0, 5)
print(arr[0]) # 取第1个元素 → 0
print(arr[2:4]) # 取第3到第4个元素(不包含5)→ [2 3]
print(arr[-1]) # 取最后1个元素 → 4
(2)2维数组:行在前,列在后
格式:arr[行索引, 列索引],用 : 表示“所有”:
arr2 = np.array([[1,2,3],[4,5,6],[7,8,9]]) # 3行3列
# 取第2行(索引从0开始,所以1是第2行)
print(arr2[1]) # 输出 [4 5 6]
# 取第3列(索引2)的所有行
print(arr2[:, 2]) # 输出 [3 6 9]
# 取第2行第3列的元素
print(arr2[1, 2]) # 输出 6
# 取第1-2行,第2列(切片)
print(arr2[0:2, 1]) # 输出 [2 5]
3. 改形状:reshape() 等方法
有时候需要把数组从“2行3列”改成“3行2列”,用这些方法:
(1)reshape():不改变原数组,返回新数组
注意:改后的形状必须满足“元素总数不变”,比如6个元素可以改成(2,3)或(3,2),但不能改成(4,2)(4×2=8≠6):
arr = np.arange(6) # [0 1 2 3 4 5],1维6个元素
# 改成2行3列
new_arr = arr.reshape(2, 3)
print(new_arr)
# 输出:
# [[0 1 2]
# [3 4 5]]
# 改成3行2列
new_arr2 = arr.reshape(3, 2)
print(new_arr2)
# 输出:
# [[0 1]
# [2 3]
# [4 5]]
(2)flatten():把多维数组“压平”成1维
arr2 = np.array([[1,2,3],[4,5,6]])
flat_arr = arr2.flatten()
print(flat_arr) # 输出 [1 2 3 4 5 6]
(3)transpose():数组转置(行变列,列变行)
比如2行3列转成3行2列:
arr2 = np.array([[1,2,3],[4,5,6]])
trans_arr = arr2.transpose()
print(trans_arr)
# 输出:
# [[1 4]
# [2 5]
# [3 6]]
五、难点突破:广播机制(Broadcasting)
这是 NumPy 里比较难理解的点,但也是很实用的功能——不同形状的数组,也能一起运算。
举个例子:用一个1行3列的数组,加一个3行1列的数组,结果是3行3列:
arr1 = np.array([[1,2,3]]) # 1行3列
arr2 = np.array([[4],[5],[6]]) # 3行1列
print(arr1 + arr2)
# 输出:
# [[5 6 7]
# [6 7 8]
# [7 8 9]]
为什么能这样算?因为 NumPy 会自动把小形状的数组“放大”(广播)到和大数组匹配:
-
arr1(1行3列)→ 放大成3行3列:[[1,2,3],[1,2,3],[1,2,3]]
-
arr2(3行1列)→ 放大成3行3列:[[4,4,4],[5,5,5],[6,6,6]]
-
然后再对应元素相加
简单记广播的核心规则:只要某一维度长度相同,或有一个是1,就能广播。如果形状完全不搭(比如(2,3)和(4,5)),就会报错。
六、NumPy 为什么这么快?3个关键原因
新手不用深入原理,但要知道它快在哪里,才明白什么时候该用:
-
向量化操作:不用循环,直接对整个数组运算,减少 Python 解释器的开销;
-
内存连续:ndarray 的元素在内存里是连续存储的,访问速度比列表(元素地址分散)快得多;
-
C语言实现:NumPy 底层是用 C 写的,执行速度比纯 Python 代码快几十甚至上百倍。
举个直观的例子:计算100万个数字的平方,NumPy 比 Python 循环快几十倍:
import numpy as np
import time
# Python 循环
start = time.time()
a = [i**2 for i in range(1000000)]
print("Python循环耗时:", time.time() - start) # 大概0.1秒
# NumPy 向量化
start = time.time()
b = np.arange(1000000) ** 2
print("NumPy耗时:", time.time() - start) # 大概0.001秒,快100倍!

七、新手必踩的4个坑,提前避开!
-
修改数组会影响原数组
ndarray 是“可变对象”,比如用 reshape() 虽然返回新数组,但如果用切片取数,修改切片会影响原数组:arr = np.array([1,2,3,4]) slice_arr = arr[1:3] # 切片是原数组的“视图”,不是副本 slice_arr[0] = 100 # 修改切片 print(arr) # 原数组也变了 → [ 1 100 3 4]解决办法:想要副本,用
copy()方法:slice_arr = arr[1:3].copy() -
数据类型转换可能丢数据
比如把浮点数(1.8)转成整数,会直接丢掉小数部分,不是四舍五入:arr = np.array([1.8, 2.3]) int_arr = arr.astype(int) # 转成整数 print(int_arr) # 输出 [1 2](不是2和2) -
切片和列表切片的区别
Python 列表切片返回的是副本,修改切片不影响原列表;但 NumPy 切片返回的是“视图”,修改会影响原数组(前面已经讲过)。 -
广播失败的问题
不是所有形状都能广播,比如(2,3)的数组和(2,4)的数组相加,会报错,因为列数3和4不匹配,也没有一个是1。

八、总结:NumPy 核心就是“高效处理数组”
学完这篇文章,你已经掌握了 NumPy 的核心用法:
-
用 ndarray 替代列表,处理数据更高效;
-
会创建数组、查属性、做运算、取数据;
-
知道广播机制的好处,避开新手坑。
NumPy 是数据分析、机器学习的“基石”——后续学 Pandas(处理表格数据)、Matplotlib(画图),都会用到 NumPy 的知识。现在就打开电脑,试着用 NumPy 创建几个数组,做几次运算,练一遍就全懂了!
最后记住:再复杂的工具,都是从“画第一个数组”开始的,加油!
跟着 Feri 学 NumPy,专注每步都成长!
更多推荐


所有评论(0)