NumPy 快速入门:从数组创建、基础函数到简单图像处理
什么是 NumPy?为什么不用原生 List?
NumPy(Numerical Python 的简称)是 Python 的一个开源扩展库,主要用于支持大量的维度数组与矩阵运算。
NumPy 为我们提供了一个特殊的数组对象 numpy.array(),我们可以用它表示普通的一维数组、二维矩阵,以及任意维度的数据。它可以对数组中的数据进行非常高效的运算,广泛应用于数据统计、图像处理、线性代数等领域。
很多初学者会问:“Python 已经有列表(List)了,为什么还要用 NumPy 的数组?”
原因主要有两点:
- 速度极快(高性能):Python 原生的 List 是一个指针数组,里面的元素分散在内存的各个角落;而 NumPy 的核心是
ndarray(N维数组),它在内存中是连续存储的,并且底层由高度优化的 C 语言代码执行。 - 向量化操作(优雅):使用原生 List 对每个元素乘以 2,你需要写一个
for循环;而在 NumPy 中,你只需要写array * 2,代码更简洁,运行速度快几十倍甚至上百倍如果你还希望将运算速度再提升一个数量级,甚至可以使用 GPU 来对这些数据做并行运算。
一、数组的创建
NumPy 中所有的计算都是围绕着数组进行的,因此在运算之前,我们需要将要计算的数据表示成数组的形式。
首先要安装: pip install numpy
然后导入 NumPy 库,并起一个别名
np:import numpy as np1.1 用
np.array()创建数组s1 = np.array([1, 2, 3, 4, 5]) print(s1)输出:
[1 2 3 4 5]1.2 用
np.zeros()创建全零数组s2 = np.zeros((3, 2)) # 传入的参数是数组的尺寸,(3,2) 代表一个三行二列的数组 print(s2) print(s2.dtype) # 查看数据类型输出:
[[0. 0.] [0. 0.] [0. 0.]] float64💡 数组默认的数据类型是 64 位浮点数(float64)。
1.3 对于现有的数组我们可以用
astype()转换数据类型t1 = s2.astype(int) print(t1)输出:
[[0 0] [0 0] [0 0]]1.4 用
np.ones()创建全一数组s3 = np.ones((2, 4)) print(s3)输出:
[[1. 1. 1. 1.] [1. 1. 1. 1.]]1.5 用
shape获取数组尺寸print(s2.shape) # (3, 2) print(s3.shape) # (2, 4)1.6 另外我们可以用
np.arange()创建一个递增或递减的数列类似于 Python 内置的
range(),区间左闭右开:s4 = np.arange(3, 7) s5 = np.arange(7, 3, -1) # 步长为 -1,递减 print(s4) print(s5)输出:
[3 4 5 6] [7 6 5 4]1.7 用
np.linspace()创建等间距数组前两个参数是区间的范围(闭区间),第三个参数是输出样本总数:
n1 = np.linspace(0, 1, 5) print(n1)输出:
[0. 0.25 0.5 0.75 1. ]
二、基本运算
在 NumPy 中,我们可以轻松地对数组进行常见的数学运算。两个相同尺寸的数组可以直接进行四则运算,它会将数组同位置的元素逐一进行加、减、乘、除:
import numpy as np a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) print(a + b) print(a / b) print(a * b) print(a * 3 + b * 2)输出:
[5 7 9] [0.25 0.4 0.5 ] [ 4 10 18] [11 16 21]💡 这种逐元素运算(Element-wise) 正是 NumPy 向量化的核心思想,避免了低效的 for 循环。
三、索引与切片
如果我们的数组是一个多维数组,想要获取数组中的某个元素,可以使用与 Python
list非常相似的语法。import numpy as np a = np.array([[1, 2, 3, 4, 5], [5, 6, 7, 8, 9]])3.1 获取单个元素
# 获取数字 7,即第二行第三列的元素(下标从 0 开始) print(a[1, 2])输出:
73.2 切片获取子数组
# 获取第一行的第 2~3 列(切片左闭右开) print(a[0, 1:3]) # 获取第一行所有列 print(a[0, :]) print(a[0]) # 冒号也可以省略输出:
[2 3] [1 2 3 4 5] [1 2 3 4 5]3.3 带跨度(Stride)的切片
在冒号后面再加一个冒号,可以指定跨度(Stride):
# 每隔两个数取一个 print(a[0, 0:5:2]) # 跨度为负值时,逆向返回数组 print(a[0, ::-2]) # 使用 ::-1 将整个数组翻转 print(a[0, ::-1])输出:
[1 3 5] [5 3 1] [5 4 3 2 1]💡
::-1翻转技巧在图像处理中非常实用,后面会用到。
四、NumPy 图像处理
了解了数组的基本操作后,我们可以对图片进行一些简单的操作。
4.1 图像与数组的关系
通常我们可以把一张灰度图看作是一个二维的数组:


数组中的每个元素表示像素点的亮度值
对于彩色的图片,我们可以用三维数组表示
数组中的第三维分别存储了像素点的红绿蓝分量

我们可以使用 Pillow 库来读取图片文件,再用 NumPy 进行处理。
4.2 完整代码
导入两张图片


import numpy as np from PIL import Image # 读取两张图片 i1 = Image.open('myImage/微信图片01.jpg') i2 = Image.open('myImage/微信图片02.jpg') # 转换为 NumPy 数组 i1 = np.array(i1) i2 = np.array(i2) # 查看数组尺寸(高, 宽, 颜色通道) print(i1.shape) # 访问某个像素点的颜色值(第100行,第100列) print(i1[100, 100]) # 单独取出所有像素点的红色分量 i1_r = i1[:, :, 0]数组尺寸:(1080, 1080, 3)
指定像素点颜色分量:[153 97 62]
单独取出所有像素点红色分量:

4.3 图片左右翻转
利用前面学到的负数跨度技巧,对列维度进行翻转:
# 对第二维(列)使用 ::-1 进行翻转 → 图片左右镜像 i2_f = i2[:, ::-1, :] Image.fromarray(i2_f).show()
仅仅一行代码
[:, ::-1, :]就实现了图片的水平翻转,这就是向量化的威力!4.4 两张图片按比例混合
# 按 4:6 的比例混合两张图片 i_a = i1 * 0.4 + i2_f * 0.6 # 运算结果为浮点数,需要转换为 uint8 才能显示图片 i_a = i_a.astype(np.uint8) Image.fromarray(i_a).show()
⚠️ 注意:混合运算后数据类型会变成
float64,PIL 无法直接处理,必须用.astype(np.uint8)转回 8 位无符号整数。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)