什么是 NumPy?为什么不用原生 List?

NumPy(Numerical Python 的简称)是 Python 的一个开源扩展库,主要用于支持大量的维度数组与矩阵运算

NumPy 为我们提供了一个特殊的数组对象 numpy.array(),我们可以用它表示普通的一维数组、二维矩阵,以及任意维度的数据。它可以对数组中的数据进行非常高效的运算,广泛应用于数据统计、图像处理、线性代数等领域。

很多初学者会问:“Python 已经有列表(List)了,为什么还要用 NumPy 的数组?”

原因主要有两点:

  1. 速度极快(高性能):Python 原生的 List 是一个指针数组,里面的元素分散在内存的各个角落;而 NumPy 的核心是 ndarray(N维数组),它在内存中是连续存储的,并且底层由高度优化的 C 语言代码执行。
  2. 向量化操作(优雅):使用原生 List 对每个元素乘以 2,你需要写一个 for 循环;而在 NumPy 中,你只需要写 array * 2,代码更简洁,运行速度快几十倍甚至上百倍

    如果你还希望将运算速度再提升一个数量级,甚至可以使用 GPU 来对这些数据做并行运算。


    一、数组的创建

    NumPy 中所有的计算都是围绕着数组进行的,因此在运算之前,我们需要将要计算的数据表示成数组的形式。

    首先要安装: pip install numpy

    然后导入 NumPy 库,并起一个别名 np

    import numpy as np
    

    1.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])
    

    输出:

    7
    

    3.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 位无符号整数。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐